diff --git a/src/azure-cli/azure/cli/command_modules/mysql/_params.py b/src/azure-cli/azure/cli/command_modules/mysql/_params.py index 7f24764a409..ad25976d739 100644 --- a/src/azure-cli/azure/cli/command_modules/mysql/_params.py +++ b/src/azure-cli/azure/cli/command_modules/mysql/_params.py @@ -122,6 +122,18 @@ def load_arguments(self, _): # pylint: disable=too-many-statements, too-many- help='Enable or disable accelerated logs. Only support for Business Critical tier. Default value is Enabled.' ) + faster_restore_arg_type = CLIArgumentType( + arg_type=get_enum_type(['Enabled', 'Disabled']), + options_list=['--faster-restore'], + help='Enable or disable Auto scale IOPS configuration for both the source and the newly restored server to enable faster restore.' + ) + + faster_provisioning_arg_type = CLIArgumentType( + arg_type=get_enum_type(['Enabled', 'Disabled']), + options_list=['--faster-provisioning'], + help='Enable or disable Auto scale IOPS configuration for both the source and the newly provisioned replica server to enable faster provisioning.' + ) + storage_redundancy_arg_type = CLIArgumentType( arg_type=get_enum_type(['LocalRedundancy', 'ZoneRedundancy']), options_list=['--storage-redundancy'], @@ -256,6 +268,12 @@ def load_arguments(self, _): # pylint: disable=too-many-statements, too-many- validator=validate_byok_identity ) + backup_interval_arg_type = CLIArgumentType( + type=int, + options_list=['--backup-interval'], + help='The interval between backups in hours. Accepted values are 24, 12 and 6. The default value is 24.' + ) + key_arg_type = CLIArgumentType( options_list=['--key'], help='The resource ID of the primary keyvault key for data encryption.' @@ -342,6 +360,7 @@ def load_arguments(self, _): # pylint: disable=too-many-statements, too-many- c.argument('accelerated_logs', arg_type=accelerated_logs_arg_type) c.argument('backup_retention', default=7, arg_type=mysql_backup_retention_arg_type) c.argument('backup_byok_identity', arg_type=backup_identity_arg_type) + c.argument('backup_interval', arg_type=backup_interval_arg_type) c.argument('backup_byok_key', arg_type=backup_key_arg_type) c.argument('byok_identity', arg_type=identity_arg_type) c.argument('byok_key', arg_type=key_arg_type) @@ -422,6 +441,7 @@ def load_arguments(self, _): # pylint: disable=too-many-statements, too-many- c.argument('storage_gb', arg_type=storage_gb_arg_type) c.argument('auto_grow', arg_type=auto_grow_arg_type) c.argument('accelerated_logs', arg_type=accelerated_logs_arg_type) + c.argument('faster_restore', arg_type=faster_restore_arg_type) c.argument('backup_retention', arg_type=mysql_backup_retention_arg_type) c.argument('geo_redundant_backup', arg_type=geo_redundant_backup_arg_type) c.argument('database_port', arg_type=database_port_arg_type) @@ -574,6 +594,7 @@ def load_arguments(self, _): # pylint: disable=too-many-statements, too-many- c.argument('storage_gb', arg_type=storage_gb_arg_type) c.argument('iops', arg_type=iops_arg_type) c.argument('storage_redundancy', arg_type=storage_redundancy_arg_type) + c.argument('faster_provisioning', arg_type=faster_provisioning_arg_type) c.argument('database_port', arg_type=database_port_arg_type) c.argument('backup_retention', arg_type=mysql_backup_retention_arg_type) c.argument('geo_redundant_backup', arg_type=geo_redundant_backup_arg_type) diff --git a/src/azure-cli/azure/cli/command_modules/mysql/_validators.py b/src/azure-cli/azure/cli/command_modules/mysql/_validators.py index 49586aa0849..1fef622c05b 100644 --- a/src/azure-cli/azure/cli/command_modules/mysql/_validators.py +++ b/src/azure-cli/azure/cli/command_modules/mysql/_validators.py @@ -105,10 +105,10 @@ def mysql_restore_tier_validator(target_tier, source_tier, sku_info): def mysql_arguments_validator(db_context, location, tier, sku_name, storage_gb, backup_retention=None, server_name=None, zone=None, standby_availability_zone=None, high_availability=None, backup_byok_key=None, public_access=None, version=None, auto_grow=None, replication_role=None, subnet=None, - byok_identity=None, backup_byok_identity=None, byok_key=None, geo_redundant_backup=None, - disable_data_encryption=None, iops=None, auto_io_scaling=None, accelerated_logs=None, - storage_redundancy=None, instance=None, data_source_type=None, mode=None, - data_source_backup_dir=None, data_source_sas_token=None): + byok_identity=None, backup_interval=None, backup_byok_identity=None, byok_key=None, + geo_redundant_backup=None, disable_data_encryption=None, iops=None, auto_io_scaling=None, + accelerated_logs=None, storage_redundancy=None, instance=None, data_source_type=None, + mode=None, data_source_backup_dir=None, data_source_sas_token=None): validate_server_name(db_context, server_name, 'Microsoft.DBforMySQL/flexibleServers') list_skus_info = get_mysql_list_skus_info(db_context.cmd, location, server_name=instance.name if instance else None) @@ -132,6 +132,7 @@ def mysql_arguments_validator(db_context, location, tier, sku_name, storage_gb, mysql_auto_grow_validator(auto_grow, replication_role, high_availability, instance) _mysql_byok_validator(byok_identity, backup_byok_identity, byok_key, backup_byok_key, disable_data_encryption, geo_redundant_backup, instance) + _mysql_backup_interval_validator(backup_interval) _mysql_iops_validator(iops, auto_io_scaling, instance) mysql_accelerated_logs_validator(accelerated_logs, tier) storage_redundancy_validator(storage_redundancy, tier) @@ -302,6 +303,13 @@ def _mysql_byok_validator(byok_identity, backup_byok_identity, byok_key, backup_ "Use the primary server instead.") +def _mysql_backup_interval_validator(backup_interval): + if backup_interval is None: + return + if backup_interval not in [6, 12, 24]: + raise ArgumentUsageError("Incorrect value for --backup-interval. Allowed values: [6, 12, 24]") + + def _mysql_iops_validator(iops, auto_io_scaling, instance): if iops is None: return diff --git a/src/azure-cli/azure/cli/command_modules/mysql/custom.py b/src/azure-cli/azure/cli/command_modules/mysql/custom.py index 0f214b5b3de..4960e1f9cea 100644 --- a/src/azure-cli/azure/cli/command_modules/mysql/custom.py +++ b/src/azure-cli/azure/cli/command_modules/mysql/custom.py @@ -339,7 +339,7 @@ def flexible_server_create(cmd, client, high_availability=None, zone=None, standby_availability_zone=None, iops=None, auto_grow=None, auto_scale_iops=None, accelerated_logs=None, storage_redundancy=None, geo_redundant_backup=None, byok_identity=None, backup_byok_identity=None, byok_key=None, backup_byok_key=None, - maintenance_policy_patch_strategy=None, yes=False): + backup_interval=None, maintenance_policy_patch_strategy=None, yes=False): # Generate missing parameters location, resource_group_name, server_name = generate_missing_parameters(cmd, location, resource_group_name, server_name) db_context = DbContext( @@ -371,6 +371,7 @@ def flexible_server_create(cmd, client, version=version, geo_redundant_backup=geo_redundant_backup, byok_identity=byok_identity, + backup_interval=backup_interval, backup_byok_identity=backup_byok_identity, byok_key=byok_key, backup_byok_key=backup_byok_key, @@ -414,7 +415,7 @@ def flexible_server_create(cmd, client, log_on_disk=accelerated_logs, storage_redundancy=storage_redundancy) - backup = models.Backup(backup_retention_days=backup_retention, geo_redundant_backup=geo_redundant_backup) + backup = models.Backup(backup_retention_days=backup_retention, backup_interval_hours=backup_interval, geo_redundant_backup=geo_redundant_backup) sku = models.MySQLServerSku(name=sku_name, tier=tier) @@ -707,8 +708,8 @@ def flexible_server_import_replica_stop(client, resource_group_name, server_name def flexible_server_restore(cmd, client, resource_group_name, server_name, source_server, restore_point_in_time=None, zone=None, no_wait=False, subnet=None, subnet_address_prefix=None, vnet=None, vnet_address_prefix=None, private_dns_zone_arguments=None, public_access=None, yes=False, sku_name=None, tier=None, database_port=None, - storage_gb=None, auto_grow=None, accelerated_logs=None, storage_redundancy=None, backup_retention=None, - geo_redundant_backup=None, tags=None): + storage_gb=None, auto_grow=None, accelerated_logs=None, faster_restore=None, storage_redundancy=None, + backup_retention=None, geo_redundant_backup=None, tags=None): provider = 'Microsoft.DBforMySQL' server_name = server_name.lower() @@ -761,6 +762,11 @@ def flexible_server_restore(cmd, client, resource_group_name, server_name, sourc else: mysql_accelerated_logs_validator(accelerated_logs, tier) + if not faster_restore: + auto_io_scaling = source_server_object.storage.auto_io_scaling + else: + auto_io_scaling = _determine_auto_io_scaling_by_faster_restore(faster_restore) + if not storage_redundancy: storage_redundancy = source_server_object.storage.storage_redundancy else: @@ -788,7 +794,7 @@ def flexible_server_restore(cmd, client, resource_group_name, server_name, sourc iops_input=source_server_object.storage.iops, tier=tier, sku_name=sku_name) storage = models.Storage(storage_size_gb=storage_gb, iops=iops, auto_grow=auto_grow, - auto_io_scaling=source_server_object.storage.auto_io_scaling, + auto_io_scaling=auto_io_scaling, log_on_disk=accelerated_logs, storage_redundancy=storage_redundancy) backup = models.Backup(backup_retention_days=backup_retention, geo_redundant_backup=geo_redundant_backup) @@ -1323,8 +1329,8 @@ def flexible_parameter_update_batch(client, server_name, resource_group_name, so # Custom functions for server replica, will add MySQL part after backend ready in future def flexible_replica_create(cmd, client, resource_group_name, source_server, replica_name, location=None, tags=None, sku_name=None, private_dns_zone_arguments=None, vnet=None, subnet=None, zone=None, public_access=None, no_wait=False, - storage_gb=None, iops=None, storage_redundancy=None, geo_redundant_backup=None, backup_retention=None, - tier=None, database_port=None): + storage_gb=None, iops=None, storage_redundancy=None, faster_provisioning=None, geo_redundant_backup=None, + backup_retention=None, tier=None, database_port=None): provider = 'Microsoft.DBforMySQL' replica_name = replica_name.lower() @@ -1369,6 +1375,11 @@ def flexible_replica_create(cmd, client, resource_group_name, source_server, rep if not iops: iops = source_server_object.storage.iops + if not faster_provisioning: + auto_io_scaling = source_server_object.storage.auto_io_scaling + else: + auto_io_scaling = _determine_auto_io_scaling_by_faster_provisioning(faster_provisioning) + if not storage_redundancy: storage_redundancy = source_server_object.storage.storage_redundancy else: @@ -1379,7 +1390,7 @@ def flexible_replica_create(cmd, client, resource_group_name, source_server, rep storage = models.Storage(storage_size_gb=storage_gb, iops=iops, auto_grow="Enabled", - auto_io_scaling=source_server_object.storage.auto_io_scaling, + auto_io_scaling=auto_io_scaling, storage_redundancy=storage_redundancy) backup = models.Backup(backup_retention_days=backup_retention, geo_redundant_backup=geo_redundant_backup) @@ -1657,6 +1668,22 @@ def _determine_iops(storage_gb, iops_info, iops_input, tier, sku_name): return iops +def _determine_auto_io_scaling_by_faster_restore(faster_restore): + if faster_restore.lower() == 'enabled': + logger.info("You have selected Faster Restore as Enabled. This will activate Auto scale IOPS configuration " + "for both the source and the newly restored server to enable faster restore. " + "You can disable the Auto scale IOPS settings later, if needed.") + return faster_restore + + +def _determine_auto_io_scaling_by_faster_provisioning(faster_restore): + if faster_restore.lower() == 'enabled': + logger.info("You have selected Faster Provisioning as Enabled. This will activate Auto scale IOPS configuration " + "for both the source and the newly provisioned replica server to enable faster provisioning. " + "You can disable the Auto scale IOPS settings later, if needed.") + return faster_restore + + def _determine_acceleratedLogs(accelerated_logs, tier): if accelerated_logs is None: if tier == "MemoryOptimized":