diff --git a/src/azure-cli/azure/cli/command_modules/rdbms/_params.py b/src/azure-cli/azure/cli/command_modules/rdbms/_params.py index 7064a8e8ab3..6451f810c68 100644 --- a/src/azure-cli/azure/cli/command_modules/rdbms/_params.py +++ b/src/azure-cli/azure/cli/command_modules/rdbms/_params.py @@ -230,6 +230,26 @@ def _flexible_server_params(command_group): actions=[LocalContextAction.SET, LocalContextAction.GET], scopes=['{} flexible-server'.format(command_group)])) + server_name_resource_arg_type = CLIArgumentType( + metavar='NAME', + options_list=['--server-name', '-s'], + id_part='name', + help="Name of the server.", + local_context_attribute=LocalContextAttribute( + name='server_name', + actions=[LocalContextAction.SET, LocalContextAction.GET], + scopes=['{} flexible-server'.format(command_group)])) + + replica_name_arg_type = CLIArgumentType( + metavar='NAME', + options_list=['--name', '-n'], + id_part='name', + help="Name of the read replica.", + local_context_attribute=LocalContextAttribute( + name='server_name', + actions=[LocalContextAction.SET, LocalContextAction.GET], + scopes=['{} flexible-server'.format(command_group)])) + migration_id_arg_type = CLIArgumentType( metavar='NAME', help="ID of the migration.", @@ -255,19 +275,6 @@ def _flexible_server_params(command_group): arg_group='Authentication' ) - database_name_create_arg_type = CLIArgumentType( - metavar='NAME', - options_list=['--database-name', '-d'], - id_part='child_name_1', - help='The name of the database to be created when provisioning the database server. ' - 'Database name must begin with a letter (a-z) or underscore (_). Subsequent characters ' - 'in a name can be letters, digits (0-9), hyphens (-), or underscores. ' - 'Database name length must be less than 64 characters.', - local_context_attribute=LocalContextAttribute( - name='database_name', - actions=[LocalContextAction.SET], - scopes=['{} flexible-server'.format(command_group)])) - database_name_arg_type = CLIArgumentType( metavar='NAME', options_list=['--database-name', '-d'], @@ -786,10 +793,7 @@ def _flexible_server_params(command_group): for scope in ['list', 'set', 'show']: argument_context_string = '{} flexible-server parameter {}'.format(command_group, scope) with self.argument_context(argument_context_string) as c: - if scope == "list": - c.argument('server_name', options_list=['--server-name', '-s'], id_part=None, arg_type=server_name_arg_type) - else: - c.argument('server_name', options_list=['--server-name', '-s'], arg_type=server_name_arg_type) + c.argument('server_name', arg_type=server_name_resource_arg_type) for scope in ['show', 'set']: argument_context_string = '{} flexible-server parameter {}'.format(command_group, scope) @@ -804,15 +808,6 @@ def _flexible_server_params(command_group): help='Source of the configuration.') # firewall-rule - for scope in ['create', 'delete', 'list', 'show', 'update']: - argument_context_string = '{} flexible-server firewall-rule {}'.format(command_group, scope) - with self.argument_context(argument_context_string) as c: - c.argument('resource_group_name', arg_type=resource_group_name_type) - if scope == "list": - c.argument('server_name', id_part=None, arg_type=server_name_arg_type) - else: - c.argument('server_name', id_part='name', arg_type=server_name_arg_type) - for scope in ['create', 'delete', 'show', 'update']: argument_context_string = '{} flexible-server firewall-rule {}'.format(command_group, scope) with self.argument_context(argument_context_string) as c: @@ -830,26 +825,18 @@ def _flexible_server_params(command_group): for scope in ['create', 'delete', 'list', 'show', 'update']: argument_context_string = '{} flexible-server db {}'.format(command_group, scope) with self.argument_context(argument_context_string) as c: - c.argument('server_name', options_list=['--server-name', '-s'], arg_type=server_name_arg_type) - - for scope in ['delete', 'list', 'show', 'update']: - argument_context_string = '{} flexible-server db {}'.format(command_group, scope) - with self.argument_context(argument_context_string) as c: + c.argument('server_name', arg_type=server_name_resource_arg_type) c.argument('database_name', arg_type=database_name_arg_type) - with self.argument_context('{} flexible-server db list'.format(command_group)) as c: - c.argument('server_name', id_part=None, options_list=['--server-name', '-s'], arg_type=server_name_arg_type) - with self.argument_context('{} flexible-server db create'.format(command_group)) as c: c.argument('charset', help='The charset of the database. The default value is UTF8') c.argument('collation', help='The collation of the database.') - c.argument('database_name', arg_type=database_name_create_arg_type) with self.argument_context('{} flexible-server db delete'.format(command_group)) as c: c.argument('yes', arg_type=yes_arg_type) with self.argument_context('{} flexible-server show-connection-string'.format(command_group)) as c: - c.argument('server_name', options_list=['--server-name', '-s'], arg_type=server_name_arg_type) + c.argument('server_name', arg_type=server_name_resource_arg_type) c.argument('administrator_login', arg_type=administrator_login_arg_type,) c.argument('administrator_login_password', arg_type=administrator_login_password_arg_type) c.argument('database_name', arg_type=database_name_arg_type) @@ -859,26 +846,21 @@ def _flexible_server_params(command_group): for scope in ['create', 'delete', 'list', 'show', 'update']: argument_context_string = '{} flexible-server virtual-endpoint {}'.format(command_group, scope) with self.argument_context(argument_context_string) as c: - c.argument('resource_group_name', arg_type=resource_group_name_type) - c.argument('server_name', options_list=['--server-name', '-s'], arg_type=server_name_arg_type) + c.argument('server_name', arg_type=server_name_resource_arg_type) c.argument('virtual_endpoint_name', options_list=['--name', '-n'], arg_type=virtual_endpoint_arg_type, validator=virtual_endpoint_name_validator) - with self.argument_context('{} flexible-server long-term-retention list'.format(command_group)) as c: - c.argument('server_name', id_part=None, arg_type=server_name_arg_type) + with self.argument_context('{} flexible-server virtual-endpoint delete'.format(command_group)) as c: + c.argument('yes', arg_type=yes_arg_type) - with self.argument_context('{} flexible-server long-term-retention show'.format(command_group)) as c: - c.argument('backup_name', options_list=['--backup-name', '-b'], help='Backup name.') - c.argument('server_name', id_part=None, arg_type=server_name_arg_type) + # long-term-retention + for scope in ['show', 'start', 'pre-check']: + argument_context_string = '{} flexible-server long-term-retention {}'.format(command_group, scope) + with self.argument_context(argument_context_string) as c: + c.argument('backup_name', options_list=['--backup-name', '-b'], help='Long-term retention backup name.') with self.argument_context('{} flexible-server long-term-retention start'.format(command_group)) as c: - c.argument('backup_name', options_list=['--backup-name', '-b'], help='The name of the new long-term-retention backup.') - c.argument('server_name', id_part=None, arg_type=server_name_arg_type) c.argument('sas_url', options_list=['--sas-url', '-u'], help='Container SAS URL.') - with self.argument_context('{} flexible-server long-term-retention pre-check'.format(command_group)) as c: - c.argument('backup_name', options_list=['--backup-name', '-b'], help='The name of the new long-term-retention backup.') - c.argument('server_name', id_part=None, arg_type=server_name_arg_type) - for scope in ['create', 'update']: argument_context_string = '{} flexible-server virtual-endpoint {}'.format(command_group, scope) with self.argument_context(argument_context_string) as c: @@ -887,16 +869,11 @@ def _flexible_server_params(command_group): c.argument('members', options_list=['--members', '-m'], arg_type=members_type, help='The read replicas the virtual endpoints point to. ') - with self.argument_context('{} flexible-server virtual-endpoint delete'.format(command_group)) as c: - c.argument('yes', arg_type=yes_arg_type) - - with self.argument_context('{} flexible-server replica list'.format(command_group)) as c: - c.argument('server_name', id_part=None, options_list=['--name', '-n'], help='Name of the source server.') - + # replica with self.argument_context('{} flexible-server replica create'.format(command_group)) as c: c.argument('source_server', arg_type=source_server_arg_type) c.argument('replica_name', options_list=['--replica-name'], - help='The name of the server to restore to.') + help='The name of the read replica.') c.argument('zone', arg_type=zone_arg_type) c.argument('location', arg_type=get_location_type(self.cli_ctx)) c.argument('vnet', arg_type=vnet_arg_type) @@ -918,14 +895,14 @@ def _flexible_server_params(command_group): help='Determines the public access. ') with self.argument_context('{} flexible-server replica promote'.format(command_group)) as c: - c.argument('server_name', arg_type=server_name_arg_type) + c.argument('replica_name', arg_type=replica_name_arg_type) c.argument('promote_mode', options_list=['--promote-mode'], required=False, arg_type=promote_mode_arg_type) c.argument('promote_option', options_list=['--promote-option'], required=False, arg_type=promote_option_arg_type) c.argument('yes', arg_type=yes_arg_type) + # deploy with self.argument_context('{} flexible-server deploy setup'.format(command_group)) as c: - c.argument('resource_group_name', arg_type=resource_group_name_type) - c.argument('server_name', options_list=['--server-name', '-s'], arg_type=server_name_arg_type) + c.argument('server_name', arg_type=server_name_resource_arg_type) c.argument('database_name', arg_type=database_name_arg_type) c.argument('administrator_login', arg_type=administrator_login_arg_type) c.argument('administrator_login_password', arg_type=administrator_login_password_arg_type) @@ -952,24 +929,29 @@ def _flexible_server_params(command_group): c.argument('max_file_size', type=int, help='The file size limitation to filter files.') # backups - if command_group != 'mariadb': - with self.argument_context('{} flexible-server backup create'.format(command_group)) as c: - c.argument('backup_name', options_list=['--backup-name', '-b'], help='The name of the new backup.') + if command_group != 'postgres': + if command_group != 'mariadb': + with self.argument_context('{} flexible-server backup create'.format(command_group)) as c: + c.argument('backup_name', options_list=['--backup-name', '-b'], help='The name of the new backup.') - with self.argument_context('{} flexible-server backup show'.format(command_group)) as c: - c.argument('backup_name', id_part='child_name_1', options_list=['--backup-name', '-b'], help='The name of the backup.') + with self.argument_context('{} flexible-server backup show'.format(command_group)) as c: + c.argument('backup_name', id_part='child_name_1', options_list=['--backup-name', '-b'], help='The name of the backup.') - with self.argument_context('{} flexible-server backup list'.format(command_group)) as c: - c.argument('server_name', id_part=None, arg_type=server_name_arg_type) + with self.argument_context('{} flexible-server backup list'.format(command_group)) as c: + c.argument('server_name', id_part=None, arg_type=server_name_arg_type) if command_group == 'postgres': + for scope in ['show', 'create', 'delete']: + argument_context_string = '{} flexible-server backup {}'.format(command_group, scope) + with self.argument_context(argument_context_string) as c: + c.argument('backup_name', id_part='child_name_1', options_list=['--backup-name', '-b'], help='The name of the backup.') + with self.argument_context('{} flexible-server backup delete'.format(command_group)) as c: - c.argument('backup_name', options_list=['--backup-name', '-b'], help='The name of the new backup.') c.argument('yes', arg_type=yes_arg_type) # identity with self.argument_context('{} flexible-server identity'.format(command_group)) as c: - c.argument('server_name', id_part=None, options_list=['--server-name', '-s'], arg_type=server_name_arg_type) + c.argument('server_name', arg_type=server_name_resource_arg_type) for scope in ['assign', 'remove']: with self.argument_context('{} flexible-server identity'.format(command_group)) as c: @@ -987,7 +969,7 @@ def _flexible_server_params(command_group): if command_group == 'postgres': for scope in ['start', 'stop', 'update-databases']: with self.argument_context('{} flexible-server fabric-mirroring'.format(command_group)) as c: - c.argument('server_name', id_part=None, options_list=['--server-name', '-s'], arg_type=server_name_arg_type) + c.argument('server_name', arg_type=server_name_resource_arg_type) c.argument('yes', arg_type=yes_arg_type) for scope in ['start', 'update-databases']: @@ -997,7 +979,7 @@ def _flexible_server_params(command_group): # microsoft-entra-admin with self.argument_context('{} flexible-server microsoft-entra-admin'.format(command_group)) as c: - c.argument('server_name', id_part=None, options_list=['--server-name', '-s'], arg_type=server_name_arg_type) + c.argument('server_name', arg_type=server_name_resource_arg_type) for scope in ['create', 'show', 'delete', 'wait']: with self.argument_context('{} flexible-server microsoft-entra-admin {}'.format(command_group, scope)) as c: @@ -1012,8 +994,7 @@ def _flexible_server_params(command_group): for scope in ['update', 'show']: argument_context_string = '{} flexible-server advanced-threat-protection-setting {}'.format(command_group, scope) with self.argument_context(argument_context_string) as c: - c.argument('resource_group_name', arg_type=resource_group_name_type) - c.argument('server_name', id_part='name', options_list=['--server-name', '-s'], arg_type=server_name_arg_type) + c.argument('server_name', arg_type=server_name_resource_arg_type) with self.argument_context('{} flexible-server advanced-threat-protection-setting update'.format(command_group)) as c: c.argument('state', @@ -1026,8 +1007,7 @@ def _flexible_server_params(command_group): for scope in ['download', 'list']: argument_context_string = '{} flexible-server server-logs {}'.format(command_group, scope) with self.argument_context(argument_context_string) as c: - c.argument('resource_group_name', arg_type=resource_group_name_type) - c.argument('server_name', id_part='name', options_list=['--server-name', '-s'], arg_type=server_name_arg_type) + c.argument('server_name', arg_type=server_name_resource_arg_type) with self.argument_context('{} flexible-server server-logs download'.format(command_group)) as c: c.argument('file_name', options_list=['--name', '-n'], nargs='+', help='Space-separated list of log filenames on the server to download.') @@ -1037,34 +1017,33 @@ def _flexible_server_params(command_group): c.argument('file_last_written', type=int, help='Integer in hours to indicate file last modify time.', default=72) c.argument('max_file_size', type=int, help='The file size limitation to filter files.') - for scope in ['list', 'show', 'delete', 'approve', 'reject']: + # private-endpoint-connection + for scope in ['show', 'delete', 'approve', 'reject']: with self.argument_context('{} flexible-server private-endpoint-connection {}'.format(command_group, scope)) as c: - c.argument('resource_group_name', arg_type=resource_group_name_type) - if scope == "list": - c.argument('server_name', options_list=['--server-name', '-s'], id_part='name', arg_type=server_name_arg_type, required=False) - else: - c.argument('server_name', options_list=['--server-name', '-s'], id_part='name', arg_type=server_name_arg_type, required=False, - help='Name of the Server. Required if --id is not specified') - c.argument('private_endpoint_connection_name', options_list=['--name', '-n'], required=False, - help='The name of the private endpoint connection associated with the Server. ' - 'Required if --id is not specified') - c.extra('connection_id', options_list=['--id'], required=False, - help='The ID of the private endpoint connection associated with the Server. ' - 'If specified --server-name/-s and --name/-n, this should be omitted.') + c.argument('server_name', arg_type=server_name_resource_arg_type, required=False) + c.argument('private_endpoint_connection_name', options_list=['--name', '-n'], required=False, + help='The name of the private endpoint connection associated with the Server. ' + 'Required if --id is not specified') + c.extra('connection_id', options_list=['--id'], required=False, + help='The ID of the private endpoint connection associated with the Server. ' + 'If specified --server-name/-s and --name/-n, this should be omitted.') if scope == "approve" or scope == "reject": c.argument('description', help='Comments for {} operation.'.format(scope), required=True) + with self.argument_context('{} flexible-server private-endpoint-connection list'.format(command_group)) as c: + c.argument('server_name', arg_type=server_name_resource_arg_type, required=False) + + # private-link-resource for scope in ['list', 'show']: with self.argument_context('{} flexible-server private-link-resource {}'.format(command_group, scope)) as c: - c.argument('resource_group_name', arg_type=resource_group_name_type) - c.argument('server_name', options_list=['--server-name', '-s'], id_part='name', arg_type=server_name_arg_type, required=False) + c.argument('server_name', arg_type=server_name_resource_arg_type) # index tuning if command_group == 'postgres': for scope in ['update', 'show', 'list-settings', 'show-settings', 'set-settings', 'list-recommendations']: argument_context_string = '{} flexible-server index-tuning {}'.format(command_group, scope) with self.argument_context(argument_context_string) as c: - c.argument('server_name', options_list=['--server-name', '-s'], arg_type=server_name_arg_type) + c.argument('server_name', arg_type=server_name_resource_arg_type) with self.argument_context('{} flexible-server index-tuning update'.format(command_group)) as c: c.argument('index_tuning_enabled', @@ -1095,7 +1074,7 @@ def _flexible_server_params(command_group): for scope in ['update', 'show', 'list-settings', 'show-settings', 'set-settings', 'list-table-recommendations', 'list-index-recommendations']: argument_context_string = '{} flexible-server autonomous-tuning {}'.format(command_group, scope) with self.argument_context(argument_context_string) as c: - c.argument('server_name', options_list=['--server-name', '-s'], arg_type=server_name_arg_type) + c.argument('server_name', arg_type=server_name_resource_arg_type) with self.argument_context('{} flexible-server autonomous-tuning update'.format(command_group)) as c: c.argument('autonomous_tuning_enabled', @@ -1135,45 +1114,37 @@ def _flexible_server_params(command_group): c.argument('server_name', id_part=None, options_list=['--server-name', '-s'], arg_type=server_name_arg_type) c.argument('yes', arg_type=yes_arg_type) + # migration handle_migration_parameters(command_group, server_name_arg_type, migration_id_arg_type) def handle_migration_parameters(command_group, server_name_arg_type, migration_id_arg_type): for scope in ['create', 'show', 'list', 'update', 'check-name-availability']: argument_context_string = '{} flexible-server migration {}'.format(command_group, scope) with self.argument_context(argument_context_string) as c: - c.argument('resource_group_name', arg_type=resource_group_name_type, - help='Resource Group Name of the migration target server.') - c.argument('server_name', id_part='name', options_list=['--name', '-n'], arg_type=server_name_arg_type, - help='Migration target server name.') + c.argument('server_name', arg_type=server_name_arg_type, help='Migration target server name.') + + if scope == "create" or scope == "update" or scope == "show" or scope == "check-name-availability": + c.argument('migration_name', arg_type=migration_id_arg_type, options_list=['--migration-name'], + help='Name of the migration.') + if scope == "create": c.argument('properties', type=file_type, completer=FilesCompleter(), options_list=['--properties', '-b'], help='Request properties. Use double or no quotes to pass in json filepath as argument.') - c.argument('migration_name', arg_type=migration_id_arg_type, options_list=['--migration-name'], - help='Name of the migration.') c.argument('migration_mode', arg_type=migration_id_arg_type, options_list=['--migration-mode'], required=False, help='Either offline or online(with CDC) migration', choices=['offline', 'online'], default='offline') c.argument('migration_option', arg_type=migration_id_arg_type, options_list=['--migration-option'], required=False, help='Supported Migration Option. Default is ValidateAndMigrate.', choices=['Validate', 'ValidateAndMigrate', 'Migrate'], default='ValidateAndMigrate') c.argument('tags', tags_type) c.argument('location', arg_type=get_location_type(self.cli_ctx)) - elif scope == "show": - c.argument('migration_name', arg_type=migration_id_arg_type, options_list=['--migration-name'], - help='Name of the migration.') elif scope == "list": - c.argument('server_name', id_part=None, arg_type=server_name_arg_type) c.argument('migration_filter', options_list=['--filter'], required=False, choices=['Active', 'All'], default='Active', help='Indicate whether all the migrations or just the Active migrations are returned. Valid values are: Active and All.') elif scope == "update": - c.argument('migration_name', arg_type=migration_id_arg_type, options_list=['--migration-name'], - help='Name of the migration.') c.argument('setup_logical_replication', options_list=['--setup-replication'], action='store_true', required=False, help='Allow the migration workflow to setup logical replication on the source. Note that this command will restart the source server.') c.argument('cutover', options_list=['--cutover'], required=False, action='store_true', help='Cut-over the data migration for all the databases in the migration. After this is complete, subsequent updates to all databases will not be migrated to the target.') c.argument('cancel', options_list=['--cancel'], required=False, action='store_true', help='Cancel the data migration for all the databases.') - elif scope == "check-name-availability": - c.argument('migration_name', arg_type=migration_id_arg_type, options_list=['--migration-name'], - help='Name of the migration.') _flexible_server_params('postgres') diff --git a/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py b/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py index c25bc4dd3f0..2e5c9081f96 100644 --- a/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py +++ b/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py @@ -832,9 +832,9 @@ def flexible_server_revivedropped(cmd, client, resource_group_name, server_name, return sdk_no_wait(no_wait, client.begin_create_or_update, resource_group_name, server_name, parameters) -def flexible_replica_promote(cmd, client, resource_group_name, server_name, promote_mode='standalone', promote_option='planned'): +def flexible_replica_promote(cmd, client, resource_group_name, replica_name, promote_mode='standalone', promote_option='planned'): validate_resource_group(resource_group_name) - if is_citus_cluster(cmd, resource_group_name, server_name): + if is_citus_cluster(cmd, resource_group_name, replica_name): # some settings validation if promote_mode.lower() == 'standalone': raise ValidationError("Standalone replica promotion on elastic cluster isn't currently supported. Please use 'switchover' instead.") @@ -842,12 +842,12 @@ def flexible_replica_promote(cmd, client, resource_group_name, server_name, prom raise ValidationError("Planned replica promotion on elastic cluster isn't currently supported. Please use 'forced' instead.") try: - server_object = client.get(resource_group_name, server_name) + server_object = client.get(resource_group_name, replica_name) except Exception as e: raise ResourceNotFoundError(e) if server_object.replica.role is not None and "replica" not in server_object.replica.role.lower(): - raise CLIError('Server {} is not a replica server.'.format(server_name)) + raise CLIError('Server {} is not a replica server.'.format(replica_name)) if promote_mode == "standalone": params = postgresql_flexibleservers.models.ServerForPatch( @@ -866,7 +866,7 @@ def flexible_replica_promote(cmd, client, resource_group_name, server_name, prom ) ) - return client.begin_update(resource_group_name, server_name, params) + return client.begin_update(resource_group_name, replica_name, params) def _create_server(db_context, cmd, resource_group_name, server_name, tags, location, sku, administrator_login, administrator_login_password, diff --git a/src/azure-cli/azure/cli/command_modules/rdbms/linter_exclusions.yml b/src/azure-cli/azure/cli/command_modules/rdbms/linter_exclusions.yml index 0092d5e2f29..f2da07e12ba 100644 --- a/src/azure-cli/azure/cli/command_modules/rdbms/linter_exclusions.yml +++ b/src/azure-cli/azure/cli/command_modules/rdbms/linter_exclusions.yml @@ -11,6 +11,33 @@ postgres flexible-server server-logs list: postgres flexible-server virtual-endpoint list: rule_exclusions: - no_ids_for_list_commands +postgres flexible-server backup list: + rule_exclusions: + - no_ids_for_list_commands +postgres flexible-server db list: + rule_exclusions: + - no_ids_for_list_commands +postgres flexible-server firewall-rule list: + rule_exclusions: + - no_ids_for_list_commands +postgres flexible-server identity list: + rule_exclusions: + - no_ids_for_list_commands +postgres flexible-server long-term-retention list: + rule_exclusions: + - no_ids_for_list_commands +postgres flexible-server microsoft-entra-admin list: + rule_exclusions: + - no_ids_for_list_commands +postgres flexible-server migration list: + rule_exclusions: + - no_ids_for_list_commands +postgres flexible-server parameter list: + rule_exclusions: + - no_ids_for_list_commands +postgres flexible-server replica list: + rule_exclusions: + - no_ids_for_list_commands postgres flexible-server revive-dropped: rule_exclusions: - missing_command_test_coverage