diff --git a/src/azure-cli/azure/cli/command_modules/appservice/_help.py b/src/azure-cli/azure/cli/command_modules/appservice/_help.py index 0370a72ecb6..61b25c332c7 100644 --- a/src/azure-cli/azure/cli/command_modules/appservice/_help.py +++ b/src/azure-cli/azure/cli/command_modules/appservice/_help.py @@ -52,13 +52,13 @@ - name: Create a Windows container app service plan. text: > az appservice plan create -g MyResourceGroup -n MyPlan --hyper-v --sku P1V3 - - name: Create an app service plan for app service environment. + - name: Create an app service plan for App Service Environment. text: > - az appservice plan create -g MyResourceGroup -n MyPlan --app-service-environment MyAppServiceEnvironment --sku I1 - - name: Create an app service plan for app service environment in different subscription. + az appservice plan create -g MyResourceGroup -n MyPlan --app-service-environment MyAppServiceEnvironment --sku I1v2 + - name: Create an app service plan for App Service Environment in different subscription. text: > az appservice plan create -g MyResourceGroup -n MyPlan --app-service-environment '/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Web/hostingEnvironments/test-ase' --sku I1V2 - - name: Create an app service plan for app service environment in different subscription and the resource group in different region than app service environment. + - name: Create an app service plan for App Service Environment in different subscription and the resource group in different region than App Service Environment. text: > az appservice plan create -g MyResourceGroup -n MyPlan --app-service-environment '/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Web/hostingEnvironments/test-ase' --sku I1V2 --location ase-region """ @@ -2521,43 +2521,43 @@ helps['appservice ase list'] = """ type: command - short-summary: List app service environments. + short-summary: List App Service Environments. examples: - - name: List all app service environments in subscription. + - name: List all App Service Environments in subscription. text: az appservice ase list - - name: List all app service environment in resource group. + - name: List all App Service Environment in resource group. text: az appservice ase list --resource-group MyResourceGroup """ helps['appservice ase show'] = """ type: command - short-summary: Show details of an app service environment. + short-summary: Show details of an App Service Environment. examples: - - name: Show app service environment. + - name: Show App Service Environment. text: az appservice ase show --name MyAseName """ helps['appservice ase list-addresses'] = """ type: command - short-summary: List VIPs associated with an app service environment v2. + short-summary: List IP addresses associated with an App Service Environment. examples: - - name: List VIPs for an app service environments. + - name: List IPs for an App Service Environment. text: az appservice ase list-addresses --name MyAseName """ helps['appservice ase list-plans'] = """ type: command - short-summary: List app service plans associated with an app service environment. + short-summary: List app service plans associated with an App Service Environment. examples: - - name: List app service plans for an app service environments. + - name: List app service plans for an App Service Environments. text: az appservice ase list-plans --name MyAseName """ helps['appservice ase create'] = """ type: command - short-summary: Create app service environment. + short-summary: Create App Service Environment. examples: - - name: Create resource group, Virtual Network and App Service Environment v3 with default values. + - name: Create resource group, Virtual Network and App Service Environment with default values. text: | az group create -g MyResourceGroup --location westeurope @@ -2565,22 +2565,22 @@ --address-prefixes 10.0.0.0/16 --subnet-name MyAseSubnet --subnet-prefixes 10.0.0.0/24 az appservice ase create -n MyAseName -g MyResourceGroup --vnet-name MyVirtualNetwork \\ - --subnet MyAseSubnet --kind asev3 - - name: Create external App Service Environments v3 in existing resource group and Virtual Network. + --subnet MyAseSubnet + - name: Create external App Service Environments in existing resource group and Virtual Network. text: | az appservice ase create -n MyAseName -g MyResourceGroup --vnet-name MyVirtualNetwork \\ - --subnet MyAseSubnet --virtual-ip-type External --kind asev3 - - name: Create Virtual Network and App Service Environment v3 in a smaller than recommended subnet in existing resource group. + --subnet MyAseSubnet --virtual-ip-type External + - name: Create Virtual Network and App Service Environment in a smaller than recommended subnet in existing resource group. text: | az network vnet create -g MyResourceGroup -n MyVirtualNetwork \\ --address-prefixes 10.0.0.0/16 --subnet-name MyAseSubnet --subnet-prefixes 10.0.0.0/26 az appservice ase create -n MyAseName -g MyResourceGroup --vnet-name MyVirtualNetwork \\ - --subnet MyAseSubnet --ignore-subnet-size-validation --kind asev3 - - name: Create external zone redundant App Service Environment v3 with default values. + --subnet MyAseSubnet --ignore-subnet-size-validation + - name: Create external zone redundant App Service Environment with default values. text: | - az appservice ase create -n MyASEv3Name -g ASEv3ResourceGroup \\ - --vnet-name MyASEv3VirtualNetwork --subnet MyASEv3Subnet --kind asev3 \\ + az appservice ase create -n MyASEName -g ASEResourceGroup \\ + --vnet-name MyASEVirtualNetwork --subnet MyASESubnet \\ --zone-redundant --virtual-ip-type External """ @@ -2596,46 +2596,42 @@ helps['appservice ase upgrade'] = """ type: command - short-summary: Upgrade app service environment v3. + short-summary: Upgrade App Service Environment. examples: - - name: Upgrade app service environment v3. + - name: Upgrade App Service Environment. text: | - az appservice ase upgrade -n MyAseV3Name -g MyResourceGroup + az appservice ase upgrade -n MyAseName -g MyResourceGroup """ helps['appservice ase send-test-notification'] = """ type: command - short-summary: Send a test upgrade notification in app service environment v3. + short-summary: Send a test upgrade notification in App Service Environment. examples: - - name: Send a test upgrade notification in app service environment v3. + - name: Send a test upgrade notification in App Service Environment. text: | - az appservice ase send-test-notification -n MyAseV3Name -g MyResourceGroup + az appservice ase send-test-notification -n MyAseName -g MyResourceGroup """ helps['appservice ase update'] = """ type: command - short-summary: Update app service environment. + short-summary: Update App Service Environment. examples: - - name: Update app service environment v2 with medium front-ends and scale factor of 10. + - name: Update App Service Environment to allow new private endpoint connections. text: | - az appservice ase update -n MyAseV2Name -g MyResourceGroup --front-end-sku I2 \\ - --front-end-scale-factor 10 - - name: Update app service environment v3 to allow new private endpoint connections. + az appservice ase update -n MyAseName -g MyResourceGroup --allow-new-private-endpoint-connections + - name: Update App Service Environment to allow incoming ftp connections. text: | - az appservice ase update -n MyAseV3Name -g MyResourceGroup --allow-new-private-endpoint-connections - - name: Update app service environment v3 to allow incoming ftp connections. + az appservice ase update -n MyAseName -g MyResourceGroup --allow-incoming-ftp-connections + - name: Update App Service Environment to allow remote debugging. text: | - az appservice ase update -n MyAseV3Name -g MyResourceGroup --allow-incoming-ftp-connections - - name: Update app service environment v3 to allow remote debugging. - text: | - az appservice ase update -n MyAseV3Name -g MyResourceGroup --allow-remote-debugging + az appservice ase update -n MyAseName -g MyResourceGroup --allow-remote-debugging """ helps['appservice ase delete'] = """ type: command - short-summary: Delete app service environment. + short-summary: Delete App Service Environment. examples: - - name: Delete app service environment. + - name: Delete App Service Environment. text: az appservice ase delete -n MyAseName """ diff --git a/src/azure-cli/azure/cli/command_modules/appservice/_params.py b/src/azure-cli/azure/cli/command_modules/appservice/_params.py index 8f0a74301cf..aa19e0c447b 100644 --- a/src/azure-cli/azure/cli/command_modules/appservice/_params.py +++ b/src/azure-cli/azure/cli/command_modules/appservice/_params.py @@ -19,7 +19,7 @@ DEPLOYMENT_STORAGE_AUTH_TYPES) from ._validators import (validate_timeout_value, validate_site_create, validate_asp_create, - validate_front_end_scale_factor, validate_ase_create, validate_ip_address, + validate_ase_create, validate_ip_address, validate_service_tag, validate_public_cloud) AUTH_TYPES = { @@ -35,8 +35,7 @@ OS_TYPES = ['Windows', 'Linux'] ACCESS_RESTRICTION_ACTION_TYPES = ['Allow', 'Deny'] ASE_LOADBALANCER_MODES = ['Internal', 'External'] -ASE_KINDS = ['ASEv2', 'ASEv3'] -ASE_OS_PREFERENCE_TYPES = ['Windows', 'Linux'] +ASE_KINDS = ['ASEv3'] PUBLIC_NETWORK_ACCESS_MODES = ['Enabled', 'Disabled'] BASIC_AUTH_TYPES = ['Enabled', 'Disabled'] DAPR_LOG_LEVELS = ['debug', 'error', 'info', 'warn'] @@ -50,9 +49,9 @@ def load_arguments(self, _): # PARAMETER REGISTRATION name_arg_type = CLIArgumentType(options_list=['--name', '-n'], metavar='NAME') sku_arg_type = CLIArgumentType( - help='The pricing tiers, e.g., F1(Free), D1(Shared), B1(Basic Small), B2(Basic Medium), B3(Basic Large), S1(Standard Small), P1V2(Premium V2 Small), P2V2(Premium V2 Medium), P3V2(Premium V2 Large), P0V3(Premium V3 Extra Small), P1V3(Premium V3 Small), P2V3(Premium V3 Medium), P3V3(Premium V3 Large), P1MV3(Premium Memory Optimized V3 Small), P2MV3(Premium Memory Optimized V3 Medium), P3MV3(Premium Memory Optimized V3 Large), P4MV3(Premium Memory Optimized V3 Extra Large), P5MV3(Premium Memory Optimized V3 Extra Extra Large), P0V4(Premium V4 Extra Small), P1V4(Premium V4 Small), P2V4(Premium V4 Medium), P3V4(Premium V4 Large), P1MV4(Premium Memory Optimized V4 Small), P2MV4(Premium Memory Optimized V4 Medium), P3MV4(Premium Memory Optimized V4 Large), P4MV4(Premium Memory Optimized V4 Extra Large), P5MV4(Premium Memory Optimized V4 Extra Extra Large), I1 (Isolated Small), I2 (Isolated Medium), I3 (Isolated Large), I1V2 (Isolated V2 I1V2), I2V2 (Isolated V2 I2V2), I3V2 (Isolated V2 I3V2), I4V2 (Isolated V2 I4V2), I5V2 (Isolated V2 I5V2), I6V2 (Isolated V2 I6V2), I1MV2 (Isolated Memory Optimized V2 I1MV2), I2MV2 (Isolated Memory Optimized V2 I2MV2), I3MV2 (Isolated Memory Optimized V2 I3MV2), I4MV2 (Isolated Memory Optimized V2 I4MV2), I5MV2 (Isolated Memory Optimized V2 I5MV2), WS1 (Logic Apps Workflow Standard 1), WS2 (Logic Apps Workflow Standard 2), WS3 (Logic Apps Workflow Standard 3)', + help='The pricing tiers, e.g., F1(Free), D1(Shared), B1(Basic Small), B2(Basic Medium), B3(Basic Large), S1(Standard Small), P1V2(Premium V2 Small), P2V2(Premium V2 Medium), P3V2(Premium V2 Large), P0V3(Premium V3 Extra Small), P1V3(Premium V3 Small), P2V3(Premium V3 Medium), P3V3(Premium V3 Large), P1MV3(Premium Memory Optimized V3 Small), P2MV3(Premium Memory Optimized V3 Medium), P3MV3(Premium Memory Optimized V3 Large), P4MV3(Premium Memory Optimized V3 Extra Large), P5MV3(Premium Memory Optimized V3 Extra Extra Large), P0V4(Premium V4 Extra Small), P1V4(Premium V4 Small), P2V4(Premium V4 Medium), P3V4(Premium V4 Large), P1MV4(Premium Memory Optimized V4 Small), P2MV4(Premium Memory Optimized V4 Medium), P3MV4(Premium Memory Optimized V4 Large), P4MV4(Premium Memory Optimized V4 Extra Large), P5MV4(Premium Memory Optimized V4 Extra Extra Large), I1V2 (Isolated V2 I1V2), I2V2 (Isolated V2 I2V2), I3V2 (Isolated V2 I3V2), I4V2 (Isolated V2 I4V2), I5V2 (Isolated V2 I5V2), I6V2 (Isolated V2 I6V2), I1MV2 (Isolated Memory Optimized V2 I1MV2), I2MV2 (Isolated Memory Optimized V2 I2MV2), I3MV2 (Isolated Memory Optimized V2 I3MV2), I4MV2 (Isolated Memory Optimized V2 I4MV2), I5MV2 (Isolated Memory Optimized V2 I5MV2), WS1 (Logic Apps Workflow Standard 1), WS2 (Logic Apps Workflow Standard 2), WS3 (Logic Apps Workflow Standard 3)', arg_type=get_enum_type( - ['F1', 'FREE', 'D1', 'SHARED', 'B1', 'B2', 'B3', 'S1', 'S2', 'S3', 'P1V2', 'P2V2', 'P3V2', 'P0V3', 'P1V3', 'P2V3', 'P3V3', 'P1MV3', 'P2MV3', 'P3MV3', 'P4MV3', 'P5MV3', 'P0V4', 'P1V4', 'P2V4', 'P3V4', 'P1MV4', 'P2MV4', 'P3MV4', 'P4MV4', 'P5MV4', 'I1', 'I2', 'I3', 'I1V2', 'I2V2', 'I3V2', 'I4V2', 'I5V2', 'I6V2', 'I1MV2', 'I2MV2', 'I3MV2', 'I4MV2', 'I5MV2', 'WS1', 'WS2', 'WS3'])) + ['F1', 'FREE', 'D1', 'SHARED', 'B1', 'B2', 'B3', 'S1', 'S2', 'S3', 'P1V2', 'P2V2', 'P3V2', 'P0V3', 'P1V3', 'P2V3', 'P3V3', 'P1MV3', 'P2MV3', 'P3MV3', 'P4MV3', 'P5MV3', 'P0V4', 'P1V4', 'P2V4', 'P3V4', 'P1MV4', 'P2MV4', 'P3MV4', 'P4MV4', 'P5MV4', 'I1V2', 'I2V2', 'I3V2', 'I4V2', 'I5V2', 'I6V2', 'I1MV2', 'I2MV2', 'I3MV2', 'I4MV2', 'I5MV2', 'WS1', 'WS2', 'WS3'])) webapp_name_arg_type = CLIArgumentType(configured_default='web', options_list=['--name', '-n'], metavar='NAME', completer=get_resource_name_completion_list('Microsoft.Web/sites'), id_part='name', @@ -72,9 +71,6 @@ def load_arguments(self, _): 'functionapp': functionapp_name_arg_type, 'logicapp': logicapp_name_arg_type } - isolated_sku_arg_type = CLIArgumentType( - help='The Isolated pricing tiers, e.g., I1 (Isolated Small), I2 (Isolated Medium), I3 (Isolated Large)', - arg_type=get_enum_type(['I1', 'I2', 'I3'])) static_web_app_sku_arg_type = CLIArgumentType( help='The pricing tiers for Static Web App', @@ -1181,22 +1177,8 @@ def load_arguments(self, _): help="Specify if app service environment should be accessible from internet") c.argument('ignore_subnet_size_validation', arg_type=get_three_state_flag(), help='Do not check if subnet is sized according to recommendations.') - c.argument('ignore_route_table', arg_type=get_three_state_flag(), - help='Configure route table manually. Applies to ASEv2 only.') - c.argument('ignore_network_security_group', arg_type=get_three_state_flag(), - help='Configure network security group manually. Applies to ASEv2 only.') - c.argument('force_route_table', arg_type=get_three_state_flag(), - help='Override route table for subnet. Applies to ASEv2 only.') - c.argument('force_network_security_group', arg_type=get_three_state_flag(), - help='Override network security group for subnet. Applies to ASEv2 only.') - c.argument('front_end_scale_factor', type=int, validator=validate_front_end_scale_factor, - help='Scale of front ends to app service plan instance ratio. Applies to ASEv2 only.', default=15) - c.argument('front_end_sku', arg_type=isolated_sku_arg_type, default='I1', - help='Size of front end servers. Applies to ASEv2 only.') - c.argument('os_preference', arg_type=get_enum_type(ASE_OS_PREFERENCE_TYPES), - help='Determine if app service environment should start with Linux workers. Applies to ASEv2 only.') c.argument('zone_redundant', arg_type=get_three_state_flag(), - help='Configure App Service Environment as Zone Redundant. Applies to ASEv3 only.') + help='Configure App Service Environment as Zone Redundant.') with self.argument_context('appservice ase delete') as c: c.argument('name', options_list=['--name', '-n'], help='Name of the app service environment') with self.argument_context('appservice ase upgrade') as c: @@ -1206,10 +1188,6 @@ def load_arguments(self, _): with self.argument_context('appservice ase update') as c: c.argument('name', options_list=['--name', '-n'], help='Name of the app service environment', local_context_attribute=LocalContextAttribute(name='ase_name', actions=[LocalContextAction.GET])) - c.argument('front_end_scale_factor', type=int, validator=validate_front_end_scale_factor, - help='(ASEv2 only) Scale of front ends to app service plan instance ratio between 5 and 15.') - c.argument('front_end_sku', arg_type=isolated_sku_arg_type, - help='(ASEv2 only) Size of front end servers.') c.argument('allow_new_private_endpoint_connections', arg_type=get_three_state_flag(), options_list=['--allow-new-private-endpoint-connections', '-p'], help='(ASEv3 only) Configure Apps in App Service Environment to allow new private endpoint connections.') diff --git a/src/azure-cli/azure/cli/command_modules/appservice/_validators.py b/src/azure-cli/azure/cli/command_modules/appservice/_validators.py index 02d077d89b9..10a6fc8417a 100644 --- a/src/azure-cli/azure/cli/command_modules/appservice/_validators.py +++ b/src/azure-cli/azure/cli/command_modules/appservice/_validators.py @@ -268,16 +268,6 @@ def validate_add_vnet(cmd, namespace): "Web app location: {}. Vnet location: {}".format(webapp_loc, vnet_loc)) -def validate_front_end_scale_factor(namespace): - if namespace.front_end_scale_factor: - min_scale_factor = 5 - max_scale_factor = 15 - scale_error_text = "Frontend Scale Factor '{}' is invalid. Must be between {} and {}" - scale_factor = namespace.front_end_scale_factor - if scale_factor < min_scale_factor or scale_factor > max_scale_factor: - raise ValidationError(scale_error_text.format(scale_factor, min_scale_factor, max_scale_factor)) - - def validate_ip_address(cmd, namespace): if namespace.ip_address is not None: _validate_ip_address_format(namespace) diff --git a/src/azure-cli/azure/cli/command_modules/appservice/appservice_environment.py b/src/azure-cli/azure/cli/command_modules/appservice/appservice_environment.py index b387e31fdcb..a11b4e0cd9c 100644 --- a/src/azure-cli/azure/cli/command_modules/appservice/appservice_environment.py +++ b/src/azure-cli/azure/cli/command_modules/appservice/appservice_environment.py @@ -51,11 +51,8 @@ def show_appserviceenvironment(cmd, name, resource_group_name=None): def create_appserviceenvironment_arm(cmd, resource_group_name, name, subnet, kind='ASEv3', - vnet_name=None, ignore_route_table=False, - ignore_network_security_group=False, virtual_ip_type='Internal', - front_end_scale_factor=None, front_end_sku=None, force_route_table=False, - force_network_security_group=False, ignore_subnet_size_validation=False, - location=None, no_wait=False, os_preference=None, zone_redundant=None): + vnet_name=None, virtual_ip_type='Internal', ignore_subnet_size_validation=False, + location=None, no_wait=False, zone_redundant=None): # The current SDK has a couple of challenges creating ASE. The current swagger version used, # did not have 201 as valid response code, and thus will fail with polling operations. # The Load Balancer Type is an Enum Flag, that is expressed as a simple string enum in swagger, @@ -68,25 +65,14 @@ def create_appserviceenvironment_arm(cmd, resource_group_name, name, subnet, kin if not ignore_subnet_size_validation: _validate_subnet_size(cmd.cli_ctx, subnet_id) - if kind == 'ASEv2': - if not ignore_route_table: - _ensure_route_table(cmd.cli_ctx, resource_group_name, name, location, subnet_id, force_route_table) - if not ignore_network_security_group: - _ensure_network_security_group(cmd.cli_ctx, resource_group_name, name, location, - subnet_id, force_network_security_group) - ase_deployment_properties = _build_ase_deployment_properties(name=name, location=location, - subnet_id=subnet_id, - virtual_ip_type=virtual_ip_type, - front_end_scale_factor=front_end_scale_factor, - front_end_sku=front_end_sku, - os_preference=os_preference) - - elif kind == 'ASEv3': - _ensure_subnet_delegation(cmd.cli_ctx, subnet_id, 'Microsoft.Web/hostingEnvironments') - ase_deployment_properties = _build_ase_deployment_properties(name=name, location=location, - subnet_id=subnet_id, kind='ASEv3', - virtual_ip_type=virtual_ip_type, - zone_redundant=zone_redundant) + if kind != 'ASEv3': + raise ValidationError('Invalid App Service Environment kind. Only ASEv3 is supported.') + + _ensure_subnet_delegation(cmd.cli_ctx, subnet_id, 'Microsoft.Web/hostingEnvironments') + ase_deployment_properties = _build_ase_deployment_properties(name=name, location=location, + subnet_id=subnet_id, kind='ASEv3', + virtual_ip_type=virtual_ip_type, + zone_redundant=zone_redundant) logger.info('Create App Service Environment...') deployment_client = _get_resource_client_factory(cmd.cli_ctx).deployments return sdk_no_wait(no_wait, deployment_client.begin_create_or_update, @@ -102,10 +88,8 @@ def delete_appserviceenvironment(cmd, name, resource_group_name=None, no_wait=Fa resource_group_name=resource_group_name, name=name) -def update_appserviceenvironment(cmd, name, resource_group_name=None, front_end_scale_factor=None, - front_end_sku=None, allow_new_private_endpoint_connections=None, - allow_incoming_ftp_connections=None, allow_remote_debugging=None, - no_wait=False): +def update_appserviceenvironment(cmd, name, resource_group_name=None, allow_new_private_endpoint_connections=None, + allow_incoming_ftp_connections=None, allow_remote_debugging=None): ase_client = _get_ase_client_factory(cmd.cli_ctx) if resource_group_name is None: resource_group_name = _get_resource_group_name_from_ase(ase_client, name) @@ -113,8 +97,6 @@ def update_appserviceenvironment(cmd, name, resource_group_name=None, front_end_ if ase_def.kind.lower() == 'asev3': ase_networking_conf = ase_client.get_ase_v3_networking_configuration(resource_group_name, name) config_update = False - if front_end_scale_factor is not None or front_end_sku is not None: - raise ValidationError('No updates were applied. The version of ASE may not be applicable to this update.') if allow_remote_debugging is not None or allow_incoming_ftp_connections is not None \ or allow_new_private_endpoint_connections is not None: if ase_networking_conf.remote_debug_enabled != allow_remote_debugging: @@ -130,21 +112,9 @@ def update_appserviceenvironment(cmd, name, resource_group_name=None, front_end_ return ase_client.update_ase_networking_configuration(resource_group_name=resource_group_name, name=name, ase_networking_configuration=ase_networking_conf) - elif ase_def.kind.lower() == 'asev2': - if allow_new_private_endpoint_connections is not None or allow_incoming_ftp_connections is not None or \ - allow_remote_debugging is not None: - raise ValidationError('No updates were applied. The version of ASE may not be applicable to this update.') - if front_end_scale_factor is not None or front_end_sku is not None: - worker_sku = _map_worker_sku(front_end_sku) - ase_def.internal_load_balancing_mode = None # Workaround issue with flag enums in Swagger - if worker_sku: - ase_def.multi_size = worker_sku - if front_end_scale_factor: - ase_def.front_end_scale_factor = front_end_scale_factor - - return sdk_no_wait(no_wait, ase_client.begin_create_or_update, resource_group_name=resource_group_name, - name=name, hosting_environment_envelope=ase_def) - raise ValidationError('No updates were applied. The version of ASE may not be applicable to this update.') + + raise ValidationError('No updates were applied. The version of ASE may not be \ + applicable to this update or no valid updates where made.') def upgrade_appserviceenvironment(cmd, name, resource_group_name=None, no_wait=False): @@ -213,9 +183,6 @@ def create_ase_inbound_services(cmd, resource_group_name, name, subnet, vnet_nam if ase.kind.lower() == 'asev3': ase_network_conf = ase_client.get_ase_v3_networking_configuration(resource_group_name, name) inbound_ip_address = ase_network_conf.internal_inbound_ip_addresses[0] - else: - ase_vip_info = ase_client.get_vip_info(resource_group_name, name) - inbound_ip_address = ase_vip_info.internal_ip_address inbound_subnet_id = _validate_subnet_id(cmd.cli_ctx, subnet, vnet_name, resource_group_name) inbound_vnet_id = _get_vnet_id_from_subnet(cmd.cli_ctx, inbound_subnet_id) @@ -299,15 +266,6 @@ def _get_vnet_id_from_subnet(cli_ctx, subnet_id): name=vnet_name) -def _map_worker_sku(sku_name): - switcher = { - 'I1': 'Standard_D1_V2', - 'I2': 'Standard_D2_V2', - 'I3': 'Standard_D3_V2' - } - return switcher.get(sku_name, None) - - def _validate_subnet_empty(cli_ctx, subnet_id): subnet_id_parts = parse_resource_id(subnet_id) vnet_resource_group = subnet_id_parts['resource_group'] @@ -376,138 +334,12 @@ def _ensure_subnet_delegation(cli_ctx, subnet_id, delegation_service_name): raise validation_error -def _ensure_route_table(cli_ctx, resource_group_name, ase_name, location, subnet_id, force): - subnet_id_parts = parse_resource_id(subnet_id) - vnet_resource_group = subnet_id_parts['resource_group'] - vnet_name = subnet_id_parts['name'] - subnet_name = subnet_id_parts['resource_name'] - ase_route_table_name = ase_name + '-Route-Table' - ase_route_name = ase_name + '-route' - - subnet_obj = Subnet.Show(cli_ctx=cli_ctx)(command_args={ - "name": subnet_name, - "vnet_name": vnet_name, - "resource_group": vnet_resource_group - }) - if subnet_obj.get("routeTable", None) is None or force: - rt_list = RouteTable.List(cli_ctx=cli_ctx)(command_args={ - "resource_group": resource_group_name - }) - rt_found = False - for rt in list(rt_list): - if rt["name"].lower() == ase_route_table_name.lower(): - rt_found = True - break - - if not rt_found: - logger.info('Ensure Route Table...') - poller = RouteTable.Create(cli_ctx=cli_ctx)(command_args={ - "name": ase_route_table_name, - "resource_group": resource_group_name, - "location": location - }) - LongRunningOperation(cli_ctx)(poller) - - logger.info('Ensure Internet Route...') - poller = RouteTableRoute.Create(cli_ctx=cli_ctx)(command_args={ - "name": ase_route_name, - "route_table_name": ase_route_table_name, - "resource_group": resource_group_name, - "address_prefix": '0.0.0.0/0', - "next_hop_type": 'Internet' - }) - LongRunningOperation(cli_ctx)(poller) - - rt = RouteTableRoute.Show(cli_ctx=cli_ctx)(command_args={ - "name": ase_route_table_name, - "resource_group": resource_group_name - }) - if not subnet_obj.get("routeTable", None) or subnet_obj["routeTable"]["id"] != rt["id"]: - logger.info('Associate Route Table with Subnet...') - poller = Subnet.Update(cli_ctx=cli_ctx)(command_args={ - "name": subnet_name, - "vnet_name": vnet_name, - "resource_group": vnet_resource_group, - "route_table": {"id": rt["id"]} - }) - LongRunningOperation(cli_ctx)(poller) - else: - route_table_id_parts = parse_resource_id(subnet_obj["routeTable"]["id"]) - rt_name = route_table_id_parts['name'] - if rt_name.lower() != ase_route_table_name.lower(): - err_msg = 'Route table already exists.' - rec_msg = 'Use --ignore-route-table to use existing route table ' \ - 'or --force-route-table to replace existing route table' - validation_error = ValidationError(err_msg) - validation_error.set_recommendation(rec_msg) - raise validation_error - - -def _ensure_network_security_group(cli_ctx, resource_group_name, ase_name, location, subnet_id, force): - subnet_id_parts = parse_resource_id(subnet_id) - vnet_resource_group = subnet_id_parts['resource_group'] - vnet_name = subnet_id_parts['name'] - subnet_name = subnet_id_parts['resource_name'] - ase_nsg_name = ase_name + '-NSG' - - subnet_obj = Subnet.Show(cli_ctx=cli_ctx)(command_args={ - "name": subnet_name, - "vnet_name": vnet_name, - "resource_group": vnet_resource_group - }) - subnet_address_prefix = subnet_obj["addressPrefix"] - if subnet_obj.get("networkSecurityGroup", None) is None or force: - nsg_list = NSG.List(cli_ctx=cli_ctx)(command_args={ - "resource_group": resource_group_name - }) - nsg_found = False - for nsg in list(nsg_list): - if nsg["name"].lower() == ase_nsg_name.lower(): - nsg_found = True - break - - if not nsg_found: - logger.info('Ensure Network Security Group...') - poller = NSG.Create(cli_ctx=cli_ctx)(command_args={ - "name": ase_nsg_name, - "resource_group": resource_group_name, - "location": location - }) - LongRunningOperation(cli_ctx)(poller) - - _create_asev2_nsg_rules(cli_ctx, resource_group_name, ase_nsg_name, subnet_address_prefix) - - nsg = NSG.Show(cli_ctx=cli_ctx)(command_args={ - "name": ase_nsg_name, - "resource_group": resource_group_name - }) - if not subnet_obj.get("networkSecurityGroup", None) or subnet_obj["networkSecurityGroup"]["id"] != nsg["id"]: - logger.info('Associate Network Security Group with Subnet...') - poller = Subnet.Update(cli_ctx=cli_ctx)(command_args={ - "name": subnet_name, - "vnet_name": vnet_name, - "resource_group": vnet_resource_group, - "network_security_group": {"id": nsg["id"]} - }) - LongRunningOperation(cli_ctx)(poller) - else: - nsg_id_parts = parse_resource_id(subnet_obj["networkSecurityGroup"]["id"]) - nsg_name = nsg_id_parts['name'] - if nsg_name.lower() != ase_nsg_name.lower(): - err_msg = 'Network Security Group already exists.' - rec_msg = 'Use --ignore-network-security-group to use existing NSG ' \ - 'or --force-network-security-group to replace existing NSG' - validation_error = ValidationError(err_msg, rec_msg) - raise validation_error - - def _get_unique_deployment_name(prefix): return prefix + random_string(16) def _build_ase_deployment_properties(name, location, subnet_id, virtual_ip_type=None, - front_end_scale_factor=None, front_end_sku=None, tags=None, - kind='ASEv2', os_preference=None, zone_redundant=None): + tags=None, kind='ASEv3', zone_redundant=None): # InternalLoadBalancingMode Enum: None 0, Web 1, Publishing 2. # External: 0 (None), Internal: 3 (Web + Publishing) ilb_mode = 3 if virtual_ip_type == 'Internal' else 0 @@ -519,13 +351,6 @@ def _build_ase_deployment_properties(name, location, subnet_id, virtual_ip_type= 'id': subnet_id } } - if front_end_scale_factor: - ase_properties['frontEndScaleFactor'] = front_end_scale_factor - if front_end_sku: - worker_sku = _map_worker_sku(front_end_sku) - ase_properties['multiSize'] = worker_sku - if os_preference: - ase_properties['osPreference'] = os_preference if zone_redundant: ase_properties['zoneRedundant'] = zone_redundant @@ -549,79 +374,6 @@ def _build_ase_deployment_properties(name, location, subnet_id, virtual_ip_type= return deployment -def _create_asev2_nsg_rules(cli_ctx, resource_group_name, ase_nsg_name, subnet_address_prefix): - logger.info('Ensure Network Security Group Rules...') - _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'Inbound-management', - 100, 'Used to manage ASE from public VIP', '*', 'Allow', 'Inbound', - '*', 'AppServiceManagement', '454-455', '*') - _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'Inbound-load-balancer-keep-alive', - 105, 'Allow communication to ASE from Load Balancer', '*', 'Allow', 'Inbound', - '*', 'AzureLoadBalancer', '16001', '*') - _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'ASE-internal-inbound', - 110, 'ASE-internal-inbound', '*', 'Allow', 'Inbound', - '*', subnet_address_prefix, '*', '*') - _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'Inbound-HTTP', - 120, 'Allow HTTP', '*', 'Allow', 'Inbound', - '*', '*', '80', '*') - _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'Inbound-HTTPS', - 130, 'Allow HTTPS', '*', 'Allow', 'Inbound', - '*', '*', '443', '*') - _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'Inbound-FTP', - 140, 'Allow FTP', '*', 'Allow', 'Inbound', - '*', '*', '21', '*') - _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'Inbound-FTPS', - 150, 'Allow FTPS', '*', 'Allow', 'Inbound', - '*', '*', '990', '*') - _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'Inbound-FTP-Data', - 160, 'Allow FTP Data', '*', 'Allow', 'Inbound', - '*', '*', '10001-10020', '*') - _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'Inbound-Remote-Debugging', - 170, 'Visual Studio remote debugging', '*', 'Allow', 'Inbound', - '*', '*', '4016-4022', '*') - _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'Outbound-443', - 100, 'Azure Storage blob', '*', 'Allow', 'Outbound', - '*', '*', '443', '*') - _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'Outbound-DB', - 110, 'Database', '*', 'Allow', 'Outbound', - '*', '*', '1433', 'Sql') - _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'Outbound-DNS', - 120, 'DNS', '*', 'Allow', 'Outbound', - '*', '*', '53', '*') - _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'ASE-internal-outbound', - 130, 'Azure Storage queue', '*', 'Allow', 'Outbound', - '*', '*', '*', subnet_address_prefix) - _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'Outbound-80', - 140, 'Outbound 80', '*', 'Allow', 'Outbound', - '*', '*', '80', '*') - _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'Outbound-monitor', - 150, 'Azure Monitor', '*', 'Allow', 'Outbound', - '*', '*', '12000', '*') - _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'Outbound-NTP', - 160, 'Clock', '*', 'Allow', 'Outbound', - '*', '*', '123', '*') - - -def _create_nsg_rule(cli_ctx, resource_group_name, network_security_group_name, security_rule_name, - priority, description=None, protocol=None, access=None, direction=None, - source_port_range='*', source_address_prefix='*', - destination_port_range=80, destination_address_prefix='*'): - poller = NSGRule.Create(cli_ctx=cli_ctx)(command_args={ - "name": security_rule_name, - "nsg_name": network_security_group_name, - "resource_group": resource_group_name, - "protocol": protocol, - "source_address_prefix": source_address_prefix, - "destination_address_prefix": destination_address_prefix, - "access": access, - "direction": direction, - "description": description, - "source_port_range": source_port_range, - "destination_port_range": destination_port_range, - "priority": priority - }) - LongRunningOperation(cli_ctx)(poller) - - def _ensure_ase_private_dns_zone(cli_ctx, resource_group_name, name, inbound_vnet_id, inbound_ip_address): # Private DNS Zone private_dns_client = _get_private_dns_client_factory(cli_ctx) diff --git a/src/azure-cli/azure/cli/command_modules/appservice/commands.py b/src/azure-cli/azure/cli/command_modules/appservice/commands.py index 0040b9fcc12..609d460a9c8 100644 --- a/src/azure-cli/azure/cli/command_modules/appservice/commands.py +++ b/src/azure-cli/azure/cli/command_modules/appservice/commands.py @@ -471,8 +471,8 @@ def load_command_table(self, _): g.custom_command('update', 'update_appserviceenvironment', supports_no_wait=True) g.custom_command('delete', 'delete_appserviceenvironment', supports_no_wait=True, confirmation=True) g.custom_command('create-inbound-services', 'create_ase_inbound_services', is_preview=True) - g.custom_command('upgrade', 'upgrade_appserviceenvironment', supports_no_wait=True, confirmation=True, is_preview=True) - g.custom_command('send-test-notification', 'send_test_notification_appserviceenvironment', is_preview=True) + g.custom_command('upgrade', 'upgrade_appserviceenvironment', supports_no_wait=True, confirmation=True) + g.custom_command('send-test-notification', 'send_test_notification_appserviceenvironment') with self.command_group('appservice domain', custom_command_type=appservice_domains, is_preview=True) as g: g.custom_command('create', 'create_domain') diff --git a/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/test_app_service_environment_commands_thru_mock.py b/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/test_app_service_environment_commands_thru_mock.py index d1e29b0b379..cd42123e040 100644 --- a/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/test_app_service_environment_commands_thru_mock.py +++ b/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/test_app_service_environment_commands_thru_mock.py @@ -58,16 +58,16 @@ def test_app_service_environment_list(self, ase_client_factory_mock): ase_client_factory_mock.return_value = ase_client host_env1 = HostingEnvironmentProfile(id='/subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/mock_rg_name_1/Microsoft.Web/hostingEnvironments/mock_ase_name_1') host_env1.name = ase_name_1 - host_env1.kind = 'ASEv2' + host_env1.kind = 'ASEv3' host_env2 = HostingEnvironmentProfile(id='/subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/mock_rg_name_2/Microsoft.Web/hostingEnvironments/mock_ase_name_2') host_env2.name = ase_name_2 host_env2.kind = 'ASEv3' ase_client.list.return_value = [host_env1, host_env2] ase_client.get.return_value = host_env1 - # Assert listvips is called (ASEv2) + # Assert get_ase_v3_networking_configuration is called (ASEv3) list_appserviceenvironment_addresses(self.mock_cmd, ase_name_1) - ase_client.get_vip_info.assert_called_with(rg_name_1, ase_name_1) + ase_client.get_ase_v3_networking_configuration.assert_called_with(rg_name_1, ase_name_1) ase_client.get.return_value = host_env2 # Assert get_ase_v3_networking_configuration is called (ASEv3) @@ -105,22 +105,20 @@ def test_app_service_environment_create(self, ase_client_factory_mock, subnet_sh show = mock.MagicMock() subnet_show_mock.return_value = show - fake_data = {"id": "1", "addressPrefix": "10.10.10.10/25"} + fake_data = {"id": "1", "addressPrefix": "10.10.10.10/25", "delegations": [{"id": "1", "serviceName": "Microsoft.Web/hostingEnvironments"}]} show.return_value = fake_data # assert that ValidationError raised when called with small subnet with self.assertRaises(ValidationError): create_appserviceenvironment_arm(self.mock_cmd, resource_group_name=rg_name, name=ase_name, subnet=subnet_name, vnet_name=vnet_name, - ignore_network_security_group=True, ignore_route_table=True, - location='westeurope', kind='ASEv2') + location='westeurope', kind='ASEv3') - fake_data = {"id": "1", "addressPrefix": "10.10.10.10/24"} + fake_data = {"id": "1", "addressPrefix": "10.10.10.10/24", "delegations": [{"id": "1", "serviceName": "Microsoft.Web/hostingEnvironments"}]} show.return_value = fake_data create_appserviceenvironment_arm(self.mock_cmd, resource_group_name=rg_name, name=ase_name, subnet=subnet_name, vnet_name=vnet_name, - ignore_network_security_group=True, ignore_route_table=True, - location='westeurope', kind='ASEv2') + location='westeurope', kind='ASEv3') # Assert begin_create_or_update is called with correct rg and deployment name resource_client_mock.deployments.begin_create_or_update.assert_called_once() @@ -128,38 +126,6 @@ def test_app_service_environment_create(self, ase_client_factory_mock, subnet_sh self.assertEqual(call_args[0][0], rg_name) self.assertEqual(call_args[0][1], deployment_name) - @mock.patch('azure.cli.command_modules.appservice.appservice_environment._get_location_from_resource_group', autospec=True) - @mock.patch('azure.cli.command_modules.appservice.appservice_environment._get_ase_client_factory', autospec=True) - def test_app_service_environment_update(self, ase_client_factory_mock, resource_group_mock): - ase_name = 'mock_ase_name' - rg_name = 'mock_rg_name' - - ase_client = mock.MagicMock() - ase_client_factory_mock.return_value = ase_client - - resource_group_mock.return_value = rg_name - - host_env = HostingEnvironmentProfile(id='/subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/mock_rg_name/Microsoft.Web/hostingEnvironments/mock_ase_name') - host_env.name = ase_name - host_env.kind = 'ASEv2' - ase_client.get.return_value = host_env - ase_client.list.return_value = [host_env] - - update_appserviceenvironment(self.mock_cmd, ase_name, front_end_scale_factor=10) - - # Assert that ValidationError raised when called with not supported parameters - with self.assertRaises(ValidationError): - update_appserviceenvironment(self.mock_cmd, ase_name, allow_new_private_endpoint_connections=True, allow_remote_debugging=True,allow_incoming_ftp_connections=True) - - # Assert create_or_update is called with correct properties - assert_host_env = HostingEnvironmentProfile(id='/subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/mock_rg_name/Microsoft.Web/hostingEnvironments/mock_ase_name') - assert_host_env.name = ase_name - assert_host_env.kind = 'ASEv2' - assert_host_env.internal_load_balancing_mode = None - assert_host_env.front_end_scale_factor = 10 - ase_client.begin_create_or_update.assert_called_once_with(resource_group_name=rg_name, name=ase_name, - hosting_environment_envelope=assert_host_env) - @mock.patch('azure.cli.command_modules.appservice.appservice_environment._get_location_from_resource_group', autospec=True) @mock.patch('azure.cli.command_modules.appservice.appservice_environment._get_ase_client_factory', autospec=True) def test_app_service_environment_update_asev3(self, ase_client_factory_mock, resource_group_mock): @@ -179,11 +145,7 @@ def test_app_service_environment_update_asev3(self, ase_client_factory_mock, res ase_networking_conf = AseV3NetworkingConfiguration(allow_new_private_endpoint_connections=False, allow_remote_debugging=False, allow_incoming_ftp_connections=False) ase_client.get_ase_v3_networking_configuration.return_value = ase_networking_conf - update_appserviceenvironment(self.mock_cmd, ase_name, allow_new_private_endpoint_connections=True, allow_remote_debugging=True,allow_incoming_ftp_connections=True) - - # assert that ValidationError raised when called with not supported parameters - with self.assertRaises(ValidationError): - update_appserviceenvironment(self.mock_cmd, ase_name, front_end_scale_factor=10) + update_appserviceenvironment(self.mock_cmd, ase_name, allow_new_private_endpoint_connections=True, allow_remote_debugging=True, allow_incoming_ftp_connections=True) # Assert create_or_update is called with correct properties ase_client.update_ase_networking_configuration.assert_called_once_with(resource_group_name=rg_name, @@ -349,27 +311,6 @@ def test_app_service_environment_send_test_notification_asev3(self, ase_client_f with self.assertRaises(ValidationError): upgrade_appserviceenvironment(self.mock_cmd, ase_name) - @mock.patch('azure.cli.command_modules.appservice.appservice_environment._get_location_from_resource_group', autospec=True) - @mock.patch('azure.cli.command_modules.appservice.appservice_environment._get_ase_client_factory', autospec=True) - def test_app_service_environment_upgrade(self, ase_client_factory_mock, resource_group_mock): - ase_name = 'mock_ase_name' - rg_name = 'mock_rg_name' - - ase_client = mock.MagicMock() - ase_client_factory_mock.return_value = ase_client - - resource_group_mock.return_value = rg_name - - host_env = HostingEnvironmentProfile(id='/subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/mock_rg_name/Microsoft.Web/hostingEnvironments/mock_ase_name') - host_env.name = ase_name - host_env.kind = 'ASEv2' - ase_client.get.return_value = host_env - ase_client.list.return_value = [host_env] - - # Assert that ValidationError raised when ASEv2 - with self.assertRaises(ValidationError): - upgrade_appserviceenvironment(self.mock_cmd, ase_name) - @mock.patch('azure.cli.command_modules.appservice.appservice_environment._get_location_from_resource_group', autospec=True) @mock.patch('azure.cli.command_modules.appservice.appservice_environment._get_ase_client_factory', autospec=True) def test_app_service_environment_upgrade_asev3(self, ase_client_factory_mock, resource_group_mock): diff --git a/src/azure-cli/azure/cli/command_modules/appservice/utils.py b/src/azure-cli/azure/cli/command_modules/appservice/utils.py index e78329b2a7e..6b5a93e6d23 100644 --- a/src/azure-cli/azure/cli/command_modules/appservice/utils.py +++ b/src/azure-cli/azure/cli/command_modules/appservice/utils.py @@ -94,8 +94,6 @@ def get_sku_tier(name): # pylint: disable=too-many-return-statements return 'PremiumContainer' if name in ['EP1', 'EP2', 'EP3']: return 'ElasticPremium' - if name in ['I1', 'I2', 'I3']: - return 'Isolated' if name in ['I1V2', 'I2V2', 'I3V2', 'I4V2', 'I5V2', 'I6V2']: return 'IsolatedV2' if name in ['I1MV2', 'I2MV2', 'I3MV2', 'I4MV2', 'I5MV2']: