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 36957d7bf18..4dc9f76f8d0 100644 --- a/src/azure-cli/azure/cli/command_modules/rdbms/_params.py +++ b/src/azure-cli/azure/cli/command_modules/rdbms/_params.py @@ -285,12 +285,14 @@ def _flexible_server_params(command_group): help='Number of IOPS to be allocated for this server. You will get certain amount of free IOPS based ' 'on compute and storage provisioned. The default value for IOPS is free IOPS. ' 'To learn more about IOPS based on compute and storage, refer to IOPS in Azure Database for MySQL Flexible Server') + c.argument('auto_grow', arg_type=get_enum_type(['Enabled', 'Disabled']), options_list=['--storage-auto-grow'], default='Enabled', + help='Enable or disable autogrow of the storage. Default value is Enabled.') c.argument('vnet_resource_id', options_list=['--vnet'], help='Name or ID of a new or existing virtual network. If you want to use a vnet from different resource group or subscription, please provide a resource ID. The name must be between 2 to 64 characters. The name must begin with a letter or number, end with a letter, number or underscore, and may contain only letters, numbers, underscores, periods, or hyphens.') c.argument('vnet_address_prefix', options_list=['--address-prefixes'], help='The IP address prefix to use when creating a new virtual network in CIDR format. Default value is 10.0.0.0/16.') c.argument('subnet_address_prefix', options_list=['--subnet-prefixes'], help='The subnet IP address prefix to use when creating a new VNet in CIDR format. Default value is 10.0.0.0/24.') c.argument('subnet_arm_resource_id', options_list=['--subnet'], - help='Name or resource ID of a new or existing subnet. If you want to use a subnet from different resource group or subscription, please provide resource ID instead of name. Please note that the subnet will be delegated to Microsoft.DBforPostgreSQL/flexibleServers/Microsoft.DBforMySQL/flexibleServers. After delegation, this subnet cannot be used for any other type of Azure resources.') + help='Name or resource ID of a new or existing subnet. If you want to use a subnet from different resource group or subscription, please provide resource ID instead of name. Please note that the subnet will be delegated to flexibleServers provider. After delegation, this subnet cannot be used for any other type of Azure resources.') c.argument('server_name', options_list=['--name', '-n'], arg_type=server_name_setter_arg_type) c.argument('location', arg_type=get_location_type(self.cli_ctx)) c.argument('administrator_login', default=generate_username(), options_list=['--admin-user', '-u'], arg_group='Authentication', arg_type=administrator_login_setter_arg_type, @@ -305,7 +307,7 @@ def _flexible_server_params(command_group): c.argument('high_availability', default="Disabled", options_list=['--high-availability'], help='Enable or disable high availability feature. Default value is Disabled. High availability can only be set during flexible server create time') c.argument('assign_identity', options_list=['--assign-identity'], help='Generate and assign an Azure Active Directory Identity for this server for use with key management services like Azure KeyVault. No need to enter extra argument.') - c.argument('private_dns_zone_arguments', options_list=['--private-dns-zone'], help='This parameter only applies for a server with private access. The name or id of new or existing private dns zone. You can use the private dns zone from same resource group, different resource group, or different subscription. If you want to use a zone from different resource group or subscription, please provide resource Id. CLI creates a new private dns zone within the same resource group if not provided by users.') + c.argument('private_dns_zone_arguments', options_list=['--private-dns-zone'], help='This parameter only applies for a server with private access. The name or id of new or existing private dns zone. You can use the private dns zone from same resource group, different resource group, or different subscription. If you want to use a zone from different resource group or subscription, please provide resource Id. CLI creates a new private dns zone within the same resource group as virtual network if not provided by users.') c.argument('database_name', id_part=None, arg_type=database_name_setter_arg_type, options_list=['--database-name', '-d'], help='The name of the database to be created when provisioning the database server') with self.argument_context('{} flexible-server delete'.format(command_group)) as c: @@ -326,6 +328,8 @@ def _flexible_server_params(command_group): help='Availability zone into which to provision the resource.') c.argument('private_dns_zone_arguments', options_list=['--private-dns-zone'], help='This parameter only applies for a server with private access. The name or id of new or existing private dns zone. You can use the private dns zone from same resource group, different resource group, or different subscription. If you want to use a zone from different resource group or subscription, please provide resource Id. CLI creates a new private dns zone within the same resource group if not provided by users.') + c.argument('subnet_arm_resource_id', options_list=['--subnet'], + help='Resource ID of an existing subnet. Please note that the subnet will be delegated to Microsoft.DBforPostgreSQL/flexibleServers if not already delegated. After delegation, this subnet cannot be used for any other type of Azure resources.') elif command_group == 'mysql': c.argument('source_server', options_list=['--source-server'], help='The name or resource ID of the source server to restore from.') diff --git a/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_common.py b/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_common.py index bbbb9ea187c..681c2f6ddc9 100644 --- a/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_common.py +++ b/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_common.py @@ -205,8 +205,8 @@ def database_delete_func(client, resource_group_name=None, server_name=None, dat "If your parameter persistence is turned OFF, consider passing them explicitly.") if not yes: user_confirmation( - "Are you sure you want to delete the server '{0}' in resource group '{1}'".format(server_name, - resource_group_name), yes=yes) + "Are you sure you want to delete the database '{0}' of server '{1}'".format(database_name, + server_name), yes=yes) try: result = client.begin_delete(resource_group_name, server_name, database_name) diff --git a/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_mysql.py b/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_mysql.py index 3efb15e97ab..d8981b91f34 100644 --- a/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_mysql.py +++ b/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_mysql.py @@ -20,7 +20,7 @@ generate_password, parse_maintenance_window, get_mysql_list_skus_info from .flexible_server_custom_common import create_firewall_rule from .flexible_server_virtual_network import prepare_private_network -from .validators import mysql_arguments_validator, validate_server_name +from .validators import mysql_arguments_validator, validate_server_name, validate_auto_grow_update, validate_mysql_ha_enabled logger = get_logger(__name__) DEFAULT_DB_NAME = 'flexibleserverdb' @@ -35,7 +35,7 @@ def flexible_server_create(cmd, client, resource_group_name=None, server_name=No administrator_login_password=None, version=None, backup_retention=None, tags=None, public_access=None, database_name=None, subnet_arm_resource_id=None, high_availability=None, zone=None, assign_identity=False, - vnet_resource_id=None, vnet_address_prefix=None, subnet_address_prefix=None, iops=None): + vnet_resource_id=None, vnet_address_prefix=None, subnet_address_prefix=None, iops=None, auto_grow=None): # Populate desired parameters location, resource_group_name, server_name = generate_missing_parameters(cmd, location, resource_group_name, @@ -95,7 +95,7 @@ def flexible_server_create(cmd, client, resource_group_name=None, server_name=No sku_name, tier, storage_mb, administrator_login, administrator_login_password, version, tags, delegated_subnet_arguments, assign_identity, public_access, - high_availability, zone, iops) + high_availability, zone, iops, auto_grow) # Adding firewall rule if public_access is not None and str(public_access).lower() != 'none': @@ -175,6 +175,7 @@ def flexible_server_update_custom_func(cmd, instance, assign_identity=False, replication_role=None, maintenance_window=None, + ha_enabled=None, iops=None): # validator location = ''.join(instance.location.lower().split()) @@ -208,7 +209,11 @@ def flexible_server_update_custom_func(cmd, instance, if backup_retention: instance.storage_profile.backup_retention_days = backup_retention + if ha_enabled: + validate_mysql_ha_enabled(instance) + if auto_grow: + validate_auto_grow_update(instance, auto_grow) instance.storage_profile.storage_autogrow = auto_grow if subnet_arm_resource_id: @@ -246,6 +251,7 @@ def flexible_server_update_custom_func(cmd, instance, ssl_enforcement=ssl_enforcement, delegated_subnet_arguments=instance.delegated_subnet_arguments, tags=tags, + ha_enabled=ha_enabled, replication_role=replication_role) if assign_identity: @@ -367,7 +373,7 @@ def flexible_list_skus(cmd, client, location): def _create_server(db_context, cmd, resource_group_name, server_name, location, backup_retention, sku_name, tier, storage_mb, administrator_login, administrator_login_password, version, tags, delegated_subnet_arguments, - assign_identity, public_network_access, ha_enabled, availability_zone, iops): + assign_identity, public_network_access, ha_enabled, availability_zone, iops, auto_grow): logging_name, server_client = db_context.logging_name, db_context.server_client logger.warning('Creating %s Server \'%s\' in group \'%s\'...', logging_name, server_name, resource_group_name) @@ -385,7 +391,8 @@ def _create_server(db_context, cmd, resource_group_name, server_name, location, storage_profile=mysql_flexibleservers.models.StorageProfile( backup_retention_days=backup_retention, storage_mb=storage_mb, - storage_iops=iops), + storage_iops=iops, + storage_autogrow=auto_grow), location=location, create_mode="Default", delegated_subnet_arguments=delegated_subnet_arguments, @@ -534,7 +541,7 @@ def _determine_iops(storage_gb, iops_info, iops_input, tier, sku_name): if iops_input and iops_input > free_iops: iops = min(iops_input, max_supported_iops) - logger.warning("IOPS is set to %d which is either your input or free/maximum IOPS supported for your storage size and SKU.", iops) + logger.warning("IOPS is %d which is either your input or free(maximum) IOPS supported for your storage size and SKU.", iops) return iops 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 3aaf2feeca0..b083c32cfdd 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 @@ -10,14 +10,15 @@ from knack.log import get_logger from azure.cli.core.commands.client_factory import get_subscription_id from azure.cli.core.local_context import ALL +from azure.cli.core.profiles import ResourceType from azure.cli.core.util import CLIError, sdk_no_wait, user_confirmation from azure.core.exceptions import ResourceNotFoundError from azure.cli.core.azclierror import RequiredArgumentMissingError, ArgumentUsageError from azure.mgmt.rdbms import postgresql_flexibleservers -from ._client_factory import cf_postgres_flexible_firewall_rules, get_postgresql_flexible_management_client, cf_postgres_flexible_db, cf_postgres_check_resource_availability -from .flexible_server_custom_common import create_firewall_rule +from ._client_factory import cf_postgres_flexible_firewall_rules, get_postgresql_flexible_management_client, cf_postgres_flexible_db, cf_postgres_check_resource_availability, resource_client_factory, network_client_factory from ._flexible_server_util import generate_missing_parameters, resolve_poller, parse_public_access_input, \ - generate_password, parse_maintenance_window, get_postgres_list_skus_info + generate_password, parse_maintenance_window, get_postgres_list_skus_info, check_existence, get_id_components +from .flexible_server_custom_common import create_firewall_rule from .flexible_server_virtual_network import prepare_private_network, prepare_private_dns_zone from .validators import pg_arguments_validator, validate_server_name @@ -132,14 +133,14 @@ def flexible_server_create(cmd, client, return _form_response(user, sku, loc, server_id, host, version, administrator_login_password if administrator_login_password is not None else '*****', - _create_postgresql_connection_string(host, user, administrator_login_password), firewall_id, + _create_postgresql_connection_string(host, user, administrator_login_password), database_name, firewall_id, subnet_id) def flexible_server_restore(cmd, client, resource_group_name, server_name, source_server, restore_point_in_time=None, location=None, zone=None, no_wait=False, - private_dns_zone_arguments=None): + private_dns_zone_arguments=None, subnet_arm_resource_id=None): provider = 'Microsoft.DBforPostgreSQL' validate_server_name(cf_postgres_check_resource_availability(cmd.cli_ctx, '_'), server_name, 'Microsoft.DBforPostgreSQL/flexibleServers') @@ -152,7 +153,7 @@ def flexible_server_restore(cmd, client, type='flexibleServers', name=source_server) else: - raise ValueError('The provided source-server {} is invalid.'.format(source_server)) + raise ValueError('The provided source server {} is invalid.'.format(source_server)) else: source_server_id = source_server @@ -166,22 +167,20 @@ def flexible_server_restore(cmd, client, location=location) # Retrieve location from same location as source server - id_parts = parse_resource_id(source_server_id) try: + id_parts = parse_resource_id(source_server_id) source_server_object = client.get(id_parts['resource_group'], id_parts['name']) parameters.location = source_server_object.location + if source_server_object.public_network_access == 'Disabled': - parameters.private_dns_zone_arguments = source_server_object.private_dns_zone_arguments - if private_dns_zone_arguments is not None: - subnet_id = source_server_object.delegated_subnet_arguments.subnet_arm_resource_id - private_dns_zone_id = prepare_private_dns_zone(cmd, - 'PostgreSQL', - resource_group_name, - server_name, - private_dns_zone=private_dns_zone_arguments, - subnet_id=subnet_id, - location=location) - parameters.private_dns_zone_arguments = postgresql_flexibleservers.models.ServerPropertiesPrivateDnsZoneArguments(private_dns_zone_arm_resource_id=private_dns_zone_id) + setup_restore_network(cmd=cmd, + resource_group_name=resource_group_name, + server_name=server_name, + location=location, + parameters=parameters, + source_server_object=source_server_object, + subnet_id=subnet_arm_resource_id, + private_dns_zone=private_dns_zone_arguments) except Exception as e: raise ResourceNotFoundError(e) @@ -189,6 +188,44 @@ def flexible_server_restore(cmd, client, return sdk_no_wait(no_wait, client.begin_create, resource_group_name, server_name, parameters) +def setup_restore_network(cmd, resource_group_name, server_name, location, parameters, source_server_object, subnet_id=None, private_dns_zone=None): + + parameters.delegated_subnet_arguments = source_server_object.delegated_subnet_arguments + parameters.private_dns_zone_arguments = source_server_object.private_dns_zone_arguments + + if subnet_id is not None: + vnet_sub, vnet_rg, vnet_name, subnet_name = get_id_components(subnet_id) + resource_client = resource_client_factory(cmd.cli_ctx, vnet_sub) + nw_client = network_client_factory(cmd.cli_ctx, subscription_id=vnet_sub) + Delegation = cmd.get_models('Delegation', resource_type=ResourceType.MGMT_NETWORK) + delegation = Delegation(name=DELEGATION_SERVICE_NAME, service_name=DELEGATION_SERVICE_NAME) + if check_existence(resource_client, subnet_name, vnet_rg, 'Microsoft.Network', 'subnets', parent_name=vnet_name, parent_type='virtualNetworks'): + subnet = nw_client.subnets.get(vnet_rg, vnet_name, subnet_name) + # Add Delegation if not delegated already + if not subnet.delegations: + logger.warning('Adding "%s" delegation to the existing subnet %s.', DELEGATION_SERVICE_NAME, subnet_name) + subnet.delegations = [delegation] + subnet = nw_client.subnets.begin_create_or_update(vnet_rg, vnet_name, subnet_name, subnet).result() + else: + for delgtn in subnet.delegations: + if delgtn.service_name != DELEGATION_SERVICE_NAME: + raise CLIError("Can not use subnet with existing delegations other than {}".format(DELEGATION_SERVICE_NAME)) + parameters.delegated_subnet_arguments = postgresql_flexibleservers.models.ServerPropertiesDelegatedSubnetArguments(subnet_arm_resource_id=subnet_id) + else: + raise ResourceNotFoundError("The subnet does not exist. Please verify the subnet Id.") + + if private_dns_zone is not None or source_server_object.private_dns_zone_arguments is None: + subnet_id = source_server_object.delegated_subnet_arguments.subnet_arm_resource_id if subnet_id is None else subnet_id + private_dns_zone_id = prepare_private_dns_zone(cmd, + 'PostgreSQL', + resource_group_name, + server_name, + private_dns_zone=private_dns_zone, + subnet_id=subnet_id, + location=location) + parameters.private_dns_zone_arguments = postgresql_flexibleservers.models.ServerPropertiesPrivateDnsZoneArguments(private_dns_zone_arm_resource_id=private_dns_zone_id) + + # Update Flexible server command def flexible_server_update_custom_func(cmd, instance, sku_name=None, @@ -438,24 +475,9 @@ def _create_postgresql_connection_string(host, user, password): return 'postgresql://{user}:{password}@{host}/postgres?sslmode=require'.format(**connection_kwargs) -def _form_response(username, sku, location, server_id, host, version, password, connection_string, firewall_id=None, +def _form_response(username, sku, location, server_id, host, version, password, connection_string, database_name, firewall_id=None, subnet_id=None): - ''' - from collections import OrderedDict - new_entry = OrderedDict() - new_entry['Id'] = server_id - if subnet_id is not None: - new_entry['SubnetId'] = subnet_id - new_entry['Location'] = location - new_entry['SkuName'] = sku - new_entry['Version'] = version - new_entry['Host'] = host - new_entry['UserName'] = username - new_entry['Password'] = password - new_entry['ConnectionString'] = connection_string - if firewall_id is not None: - new_entry['FirewallName'] = firewall_id - ''' + output = { 'host': host, 'username': username, @@ -464,6 +486,7 @@ def _form_response(username, sku, location, server_id, host, version, password, 'location': location, 'id': server_id, 'version': version, + 'databaseName': database_name, 'connectionString': connection_string } if firewall_id is not None: diff --git a/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_virtual_network.py b/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_virtual_network.py index 1445225eb9d..5eae257b955 100644 --- a/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_virtual_network.py +++ b/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_virtual_network.py @@ -16,6 +16,7 @@ from azure.mgmt.privatedns.models import VirtualNetworkLink from ._client_factory import resource_client_factory, network_client_factory, private_dns_client_factory, private_dns_link_client_factory, cf_postgres_flexible_private_dns_zone_suffix_operations from ._flexible_server_util import get_id_components, check_existence +from .validators import validate_private_dns_zone logger = get_logger(__name__) DEFAULT_VNET_ADDRESS_PREFIX = '10.0.0.0/16' @@ -214,6 +215,8 @@ def prepare_private_dns_zone(cmd, database_engine, resource_group, server_name, elif _check_if_resource_name(private_dns_zone) and private_dns_zone[-len(private_dns_zone_suffix):] != private_dns_zone_suffix: raise ValidationError('The suffix of the private DNS zone should be in "{}" format'.format(private_dns_zone_suffix)) + validate_private_dns_zone(cmd, server_name=server_name, private_dns_zone=private_dns_zone) + link = VirtualNetworkLink(location='global', virtual_network=SubResource(id=vnet.id)) link.registration_enabled = False diff --git a/src/azure-cli/azure/cli/command_modules/rdbms/tests/latest/test_rdbms_flexible_commands_mysql.py b/src/azure-cli/azure/cli/command_modules/rdbms/tests/latest/test_rdbms_flexible_commands_mysql.py index 7c5829b7609..c97ccc27288 100644 --- a/src/azure-cli/azure/cli/command_modules/rdbms/tests/latest/test_rdbms_flexible_commands_mysql.py +++ b/src/azure-cli/azure/cli/command_modules/rdbms/tests/latest/test_rdbms_flexible_commands_mysql.py @@ -176,57 +176,6 @@ def test_mysql_flexible_server_iops_delete(self): self.cmd('az group delete --name {} --yes --no-wait'.format(self.resource_group)) -class MySqlFlexibleServerVnetServerMgmtScenarioTest(FlexibleServerVnetServerMgmtScenarioTest): - - def __init__(self, method_name): - super(MySqlFlexibleServerVnetServerMgmtScenarioTest, self).__init__(method_name) - self.location = mysql_location - self.resource_group = self.create_random_name(RG_NAME_PREFIX, RG_NAME_MAX_LENGTH) - self.server = self.create_random_name(SERVER_NAME_PREFIX, SERVER_NAME_MAX_LENGTH) - self.server_2 = self.create_random_name(SERVER_NAME_PREFIX + '2', SERVER_NAME_MAX_LENGTH) - self.restore_server = 'restore-' + self.server[:55] - self.restore_server_2 = 'restore-' + self.server_2[:55] - - @pytest.mark.order(1) - def test_mysql_flexible_server_vnet_server_prepare(self): - self.cmd('az group create --location {} --name {}'.format(mysql_location, self.resource_group)) - - @AllowLargeResponse() - @pytest.mark.order(2) - def test_mysql_flexible_server_vnet_server_create(self): - self._test_flexible_server_vnet_server_create('mysql', self.resource_group, self.server) - - @AllowLargeResponse() - @pytest.mark.order(3) - def test_mysql_flexible_server_vnet_server_update_scale_up(self): - self._test_flexible_server_vnet_server_update_scale_up('mysql', self.resource_group, self.server) - - @AllowLargeResponse() - @pytest.mark.order(4) - def test_mysql_flexible_server_vnet_server_restore(self): - self._test_flexible_server_vnet_server_restore('mysql', self.resource_group, self.server, self.restore_server) - - @AllowLargeResponse() - @pytest.mark.order(5) - def test_mysql_flexible_server_vnet_ha_server_create(self): - self._test_flexible_server_vnet_ha_server_create('mysql', self.resource_group, self.server_2) - - @AllowLargeResponse() - @pytest.mark.order(6) - def test_mysql_flexible_server_vnet_ha_server_update_scale_up(self): - self._test_flexible_server_vnet_server_update_scale_up('mysql', self.resource_group, self.server_2) - - @AllowLargeResponse() - @pytest.mark.order(7) - def test_mysql_flexible_server_vnet_ha_server_delete(self): - self._test_flexible_server_vnet_server_delete('mysql', self.resource_group, self.server_2) - - @AllowLargeResponse() - @pytest.mark.order(8) - def test_mysql_flexible_server_vnet_server_delete(self): - self._test_flexible_server_vnet_server_delete('mysql', self.resource_group, self.server, self.restore_server) - - class MySqlFlexibleServerProxyResourceMgmtScenarioTest(FlexibleServerProxyResourceMgmtScenarioTest): mysql_location = mysql_location diff --git a/src/azure-cli/azure/cli/command_modules/rdbms/tests/latest/test_rdbms_flexible_commands_postgres.py b/src/azure-cli/azure/cli/command_modules/rdbms/tests/latest/test_rdbms_flexible_commands_postgres.py index ce441a408dc..2fc85923095 100644 --- a/src/azure-cli/azure/cli/command_modules/rdbms/tests/latest/test_rdbms_flexible_commands_postgres.py +++ b/src/azure-cli/azure/cli/command_modules/rdbms/tests/latest/test_rdbms_flexible_commands_postgres.py @@ -214,66 +214,6 @@ def test_postgres_flexible_server_high_availability_delete(self): self._test_flexible_server_high_availability_delete(self.resource_group) -class PostgresFlexibleServerVnetServerMgmtScenarioTest(FlexibleServerVnetServerMgmtScenarioTest): - - def __init__(self, method_name): - super(PostgresFlexibleServerVnetServerMgmtScenarioTest, self).__init__(method_name) - self.location = postgres_location - self.resource_group = self.create_random_name(RG_NAME_PREFIX, RG_NAME_MAX_LENGTH) - self.server = self.create_random_name(SERVER_NAME_PREFIX, SERVER_NAME_MAX_LENGTH) - self.server_2 = self.create_random_name(SERVER_NAME_PREFIX + '2', SERVER_NAME_MAX_LENGTH) - self.restore_server = 'restore-' + self.server[:55] - self.restore_server_2 = 'restore-' + self.server_2[:55] - - @pytest.mark.order(1) - def test_postgres_flexible_server_vnet_server_prepare(self): - self.cmd('az group create --location {} --name {}'.format(postgres_location, self.resource_group)) - - @AllowLargeResponse() - @pytest.mark.order(2) - def test_postgres_flexible_server_vnet_server_create(self): - self._test_flexible_server_vnet_server_create('postgres', self.resource_group, self.server) - - @AllowLargeResponse() - @pytest.mark.order(3) - def test_postgres_flexible_server_vnet_server_update_scale_up(self): - self._test_flexible_server_vnet_server_update_scale_up('postgres', self.resource_group, self.server) - - @AllowLargeResponse() - @pytest.mark.order(4) - def test_postgres_flexible_server_vnet_server_restore(self): - self._test_flexible_server_vnet_server_restore('postgres', self.resource_group, self.server, self.restore_server) - - @AllowLargeResponse() - @pytest.mark.order(5) - def test_postgres_flexible_server_vnet_server_delete(self): - self._test_flexible_server_vnet_server_delete('postgres', self.resource_group, self.server, self.restore_server) - - @AllowLargeResponse() - @pytest.mark.order(6) - def test_postgres_flexible_server_vnet_ha_server_create(self): - self._test_flexible_server_vnet_ha_server_create('postgres', self.resource_group, self.server_2) - - @AllowLargeResponse() - @pytest.mark.order(7) - def test_postgres_flexible_server_vnet_ha_server_update_scale_up(self): - self._test_flexible_server_vnet_server_update_scale_up('postgres', self.resource_group, self.server_2) - - @AllowLargeResponse() - @pytest.mark.order(8) - def test_postgres_flexible_server_vnet_ha_server_restore(self): - self._test_flexible_server_vnet_server_restore('postgres', self.resource_group, self.server_2, self.restore_server_2) - - @AllowLargeResponse() - @pytest.mark.order(9) - def test_postgres_flexible_server_vnet_ha_server_delete(self): - self._test_flexible_server_vnet_server_delete('postgres', self.resource_group, self.server_2, self.restore_server_2) - - @pytest.mark.order(10) - def test_postgres_flexible_server_vnet_server_mgmt_delete(self): - self._test_flexible_server_vnet_server_mgmt_delete(self.resource_group) - - class PostgresFlexibleServerProxyResourceMgmtScenarioTest(FlexibleServerProxyResourceMgmtScenarioTest): postgres_location = postgres_location diff --git a/src/azure-cli/azure/cli/command_modules/rdbms/validators.py b/src/azure-cli/azure/cli/command_modules/rdbms/validators.py index bafa0286d9d..8827979dedc 100644 --- a/src/azure-cli/azure/cli/command_modules/rdbms/validators.py +++ b/src/azure-cli/azure/cli/command_modules/rdbms/validators.py @@ -293,7 +293,30 @@ def _valid_range(addr_range): def validate_server_name(client, server_name, type_): + if len(server_name) < 3 or len(server_name) > 63: + raise ValidationError("Server name must be at least 3 characters and at most 63 characters.") + result = client.execute(name_availability_request={'name': server_name, 'type': type_}) if not result.name_available: - raise ValidationError("The name is already in use. Please provide a different name.") + raise ValidationError(result.message) + + +def validate_auto_grow_update(server, auto_grow): + # if replica, cannot be disabled + if server.replication_role != 'None' and auto_grow.lower() == 'disabled': + raise ValidationError("Auto grow feature for replica server cannot be disabled.") + # if ha, cannot be disabled + if server.ha_state != 'NotEnabled' and auto_grow.lower() == 'disabled': + raise ValidationError("Auto grow feature for high availability server cannot be disabled.") + + +def validate_private_dns_zone(cmd, server_name, private_dns_zone): + postgresql_server_endpoint = cmd.cli_ctx.cloud.suffixes.postgresql_server_endpoint + if private_dns_zone == server_name + postgresql_server_endpoint: + raise ValidationError("private dns zone name cannot be same as the server's fully qualified domain name") + + +def validate_mysql_ha_enabled(server): + if server.storage_profile.storage_autogrow == "Disabled": + raise ValidationError("You need to enable auto grow first to enable high availability.")