1010from azure .mgmt .privatedns import PrivateDnsManagementClient
1111
1212# Models
13- from azure .mgmt .network .models import (RouteTable , Route , NetworkSecurityGroup , SecurityRule , Delegation ,
14- PrivateEndpoint , Subnet , PrivateLinkServiceConnection )
13+ from azure .mgmt .network .models import (RouteTable , Route , NetworkSecurityGroup , SecurityRule , Delegation )
1514from azure .mgmt .resource .resources .models import (DeploymentProperties , Deployment , SubResource )
1615from azure .mgmt .privatedns .models import (PrivateZone , VirtualNetworkLink , RecordSet , ARecord )
1716
@@ -50,7 +49,7 @@ def create_appserviceenvironment_arm(cmd, resource_group_name, name, subnet, kin
5049 ignore_network_security_group = False , virtual_ip_type = 'Internal' ,
5150 front_end_scale_factor = None , front_end_sku = None , force_route_table = False ,
5251 force_network_security_group = False , ignore_subnet_size_validation = False ,
53- location = None , no_wait = False , os_preference = None ):
52+ location = None , no_wait = False , os_preference = None , zone_redundant = None ):
5453 # The current SDK has a couple of challenges creating ASE. The current swagger version used,
5554 # did not have 201 as valid response code, and thus will fail with polling operations.
5655 # The Load Balancer Type is an Enum Flag, that is expressed as a simple string enum in swagger,
@@ -79,7 +78,9 @@ def create_appserviceenvironment_arm(cmd, resource_group_name, name, subnet, kin
7978 elif kind == 'ASEv3' :
8079 _ensure_subnet_delegation (cmd .cli_ctx , subnet_id , 'Microsoft.Web/hostingEnvironments' )
8180 ase_deployment_properties = _build_ase_deployment_properties (name = name , location = location ,
82- subnet_id = subnet_id , kind = 'ASEv3' )
81+ subnet_id = subnet_id , kind = 'ASEv3' ,
82+ virtual_ip_type = virtual_ip_type ,
83+ zone_redundant = zone_redundant )
8384 logger .info ('Create App Service Environment...' )
8485 deployment_client = _get_resource_client_factory (cmd .cli_ctx ).deployments
8586 return sdk_no_wait (no_wait , deployment_client .begin_create_or_update ,
@@ -122,8 +123,8 @@ def list_appserviceenvironment_addresses(cmd, name, resource_group_name=None):
122123 resource_group_name = _get_resource_group_name_from_ase (ase_client , name )
123124 ase = ase_client .get (resource_group_name , name )
124125 if ase .kind .lower () == 'asev3' :
125- raise CommandNotFoundError ( 'list-addresses is currently not supported for ASEv3. '
126- 'Inbound IP is associated with the private endpoint .' )
126+ # return ase_client.get_ase_v3_networking_configuration(resource_group_name, name) # pending SDK update
127+ raise CommandNotFoundError ( 'list-addresses is currently not supported for ASEv3 .' )
127128 return ase_client .get_vip_info (resource_group_name , name )
128129
129130
@@ -140,34 +141,23 @@ def create_ase_inbound_services(cmd, resource_group_name, name, subnet, vnet_nam
140141 if not ase :
141142 raise ResourceNotFoundError ("App Service Environment '{}' not found." .format (name ))
142143
144+ if ase .internal_load_balancing_mode == 'None' :
145+ raise ValidationError ('Private DNS Zone is not relevant for External ASE.' )
146+
147+ if ase .kind .lower () == 'asev3' :
148+ # pending SDK update (ase_client.get_ase_v3_networking_configuration(resource_group_name, name))
149+ raise CommandNotFoundError ('create-inbound-services is currently not supported for ASEv3.' )
150+
151+ ase_vip_info = ase_client .get_vip_info (resource_group_name , name )
152+ inbound_ip_address = ase_vip_info .internal_ip_address
143153 inbound_subnet_id = _validate_subnet_id (cmd .cli_ctx , subnet , vnet_name , resource_group_name )
144154 inbound_vnet_id = _get_vnet_id_from_subnet (cmd .cli_ctx , inbound_subnet_id )
145- if ase .kind .lower () == 'asev3' :
146- _ensure_subnet_private_endpoint_network_policy (cmd .cli_ctx , inbound_subnet_id , False )
147- network_client = _get_network_client_factory (cmd .cli_ctx )
148- pls_connection = PrivateLinkServiceConnection (private_link_service_id = ase .id ,
149- group_ids = ['hostingEnvironments' ],
150- request_message = 'Link from CLI' ,
151- name = '{}-private-connection' .format (name ))
152- private_endpoint = PrivateEndpoint (location = ase .location , tags = None , subnet = Subnet (id = inbound_subnet_id ))
153- private_endpoint .private_link_service_connections = [pls_connection ]
154- poller = network_client .private_endpoints .begin_create_or_update (resource_group_name ,
155- '{}-private-endpoint' .format (name ),
156- private_endpoint )
157- LongRunningOperation (cmd .cli_ctx )(poller )
158- ase_pe = poller .result ()
159- nic_name = parse_resource_id (ase_pe .network_interfaces [0 ].id )['name' ]
160- nic = network_client .network_interfaces .get (resource_group_name , nic_name )
161- inbound_ip_address = nic .ip_configurations [0 ].private_ip_address
162- elif ase .kind .lower () == 'asev2' :
163- if ase .internal_load_balancing_mode == 0 :
164- raise ValidationError ('Private DNS Zone is not relevant for External ASEv2.' )
165- ase_vip_info = ase_client .get_vip_info (resource_group_name , name )
166- inbound_ip_address = ase_vip_info .internal_ip_address
167155
168156 if not skip_dns :
169157 _ensure_ase_private_dns_zone (cmd .cli_ctx , resource_group_name = resource_group_name , name = name ,
170158 inbound_vnet_id = inbound_vnet_id , inbound_ip_address = inbound_ip_address )
159+ else :
160+ logger .warning ('Parameter --skip-dns is deprecated.' )
171161
172162
173163def _get_ase_client_factory (cli_ctx , api_version = None ):
@@ -288,29 +278,6 @@ def _validate_subnet_size(cli_ctx, subnet_id):
288278 raise validation_error
289279
290280
291- def _ensure_subnet_private_endpoint_network_policy (cli_ctx , subnet_id , network_policy_enabled ):
292- network_client = _get_network_client_factory (cli_ctx )
293- subnet_id_parts = parse_resource_id (subnet_id )
294- vnet_resource_group = subnet_id_parts ['resource_group' ]
295- vnet_name = subnet_id_parts ['name' ]
296- subnet_name = subnet_id_parts ['resource_name' ]
297- subnet_obj = network_client .subnets .get (vnet_resource_group , vnet_name , subnet_name )
298- target_state = 'Enabled' if network_policy_enabled else 'Disabled'
299-
300- if subnet_obj .private_endpoint_network_policies != target_state :
301- subnet_obj .private_endpoint_network_policies = target_state
302- try :
303- poller = network_client .subnets .begin_create_or_update (
304- vnet_resource_group , vnet_name , subnet_name , subnet_parameters = subnet_obj )
305- LongRunningOperation (cli_ctx )(poller )
306- except Exception :
307- err_msg = 'Subnet must have Private Endpoint Network Policy {}.' .format (target_state )
308- rec_msg = 'Use: az network vnet subnet update --disable-private-endpoint-network-policies'
309- validation_error = ValidationError (err_msg )
310- validation_error .set_recommendation (rec_msg )
311- raise validation_error
312-
313-
314281def _ensure_subnet_delegation (cli_ctx , subnet_id , delegation_service_name ):
315282 network_client = _get_network_client_factory (cli_ctx )
316283 subnet_id_parts = parse_resource_id (subnet_id )
@@ -441,7 +408,7 @@ def _get_unique_deployment_name(prefix):
441408
442409def _build_ase_deployment_properties (name , location , subnet_id , virtual_ip_type = None ,
443410 front_end_scale_factor = None , front_end_sku = None , tags = None ,
444- kind = 'ASEv2' , os_preference = None ):
411+ kind = 'ASEv2' , os_preference = None , zone_redundant = None ):
445412 # InternalLoadBalancingMode Enum: None 0, Web 1, Publishing 2.
446413 # External: 0 (None), Internal: 3 (Web + Publishing)
447414 ilb_mode = 3 if virtual_ip_type == 'Internal' else 0
@@ -460,6 +427,8 @@ def _build_ase_deployment_properties(name, location, subnet_id, virtual_ip_type=
460427 ase_properties ['multiSize' ] = worker_sku
461428 if os_preference :
462429 ase_properties ['osPreference' ] = os_preference
430+ if zone_redundant :
431+ ase_properties ['zoneRedundant' ] = zone_redundant
463432
464433 ase_resource = {
465434 'name' : name ,
@@ -555,15 +524,15 @@ def _ensure_ase_private_dns_zone(cli_ctx, resource_group_name, name, inbound_vne
555524 private_dns_client = _get_private_dns_client_factory (cli_ctx )
556525 zone_name = '{}.appserviceenvironment.net' .format (name )
557526 zone = PrivateZone (location = 'global' , tags = None )
558- poller = private_dns_client .private_zones .create_or_update (resource_group_name , zone_name , zone )
527+ poller = private_dns_client .private_zones .begin_create_or_update (resource_group_name , zone_name , zone )
559528 LongRunningOperation (cli_ctx )(poller )
560529
561530 link_name = '{}_link' .format (name )
562531 link = VirtualNetworkLink (location = 'global' , tags = None )
563532 link .virtual_network = SubResource (id = inbound_vnet_id )
564533 link .registration_enabled = False
565- private_dns_client .virtual_network_links .create_or_update (resource_group_name , zone_name ,
566- link_name , link , if_none_match = '*' )
534+ private_dns_client .virtual_network_links .begin_create_or_update (resource_group_name , zone_name ,
535+ link_name , link , if_none_match = '*' )
567536 ase_record = ARecord (ipv4_address = inbound_ip_address )
568537 record_set = RecordSet (ttl = 3600 )
569538 record_set .a_records = [ase_record ]
0 commit comments