def validate_address_prefixes(namespace): if namespace.subnet_type != 'new': validate_parameter_set(namespace, required=[], forbidden=['subnet_address_prefix', 'vnet_address_prefix'], description='existing subnet')
def validate_address_prefixes(namespace): if namespace.subnet_type != 'new': validate_parameter_set(namespace, required=[], forbidden=['subnet_address_prefix', 'vnet_address_prefix'], description='existing subnet')
def _validate_vmss_create_load_balancer_or_app_gateway(namespace): INSTANCE_THRESHOLD = _get_vmss_create_instance_threshold() # convert the single_placement_group to boolean for simpler logic beyond if namespace.single_placement_group is None: namespace.single_placement_group = namespace.instance_count <= INSTANCE_THRESHOLD else: namespace.single_placement_group = ( namespace.single_placement_group == 'true') if not namespace.single_placement_group and namespace.load_balancer: raise CLIError( '--load-balancer is not applicable when --single-placement-group is turned off.' ) if namespace.load_balancer and namespace.application_gateway: raise CLIError('incorrect usage: --load-balancer NAME_OR_ID | ' '--application-gateway NAME_OR_ID') if namespace.instance_count > INSTANCE_THRESHOLD and namespace.load_balancer: raise CLIError( '--load-balancer cannot be used with --instance_count is > {}'. format(INSTANCE_THRESHOLD)) # Resolve the type of balancer (if any) being used balancer_type = 'None' if namespace.load_balancer is None and namespace.application_gateway is None: # use defaulting rules to determine balancer_type = 'loadBalancer' if namespace.instance_count <= INSTANCE_THRESHOLD \ else 'applicationGateway' logger.debug("defaulting to '%s' because instance count <= %s", balancer_type, INSTANCE_THRESHOLD) elif namespace.load_balancer: balancer_type = 'loadBalancer' elif namespace.application_gateway: balancer_type = 'applicationGateway' if balancer_type == 'applicationGateway': if namespace.application_gateway: client = get_network_client().application_gateways try: client.get(namespace.resource_group_name, namespace.application_gateway) namespace.app_gateway_type = 'existing' namespace.backend_pool_name = namespace.backend_pool_name or \ _get_default_address_pool(namespace.resource_group_name, namespace.application_gateway, 'application_gateways') logger.debug( "using specified existing application gateway '%s'", namespace.application_gateway) except CloudError: namespace.app_gateway_type = 'new' logger.debug( "application gateway '%s' not found. It will be created.", namespace.application_gateway) elif namespace.application_gateway == '': namespace.app_gateway_type = None logger.debug('no application gateway will be used') elif namespace.application_gateway is None: namespace.app_gateway_type = 'new' logger.debug('new application gateway will be created') # AppGateway frontend required = [] if namespace.app_gateway_type == 'new': required.append('app_gateway_sku') required.append('app_gateway_capacity') if namespace.vnet_type != 'new': required.append('app_gateway_subnet_address_prefix') elif namespace.app_gateway_type == 'existing': required.append('backend_pool_name') forbidden = ['nat_pool_name', 'load_balancer'] validate_parameter_set( namespace, required, forbidden, description='network balancer: application gateway') elif balancer_type == 'loadBalancer': # LoadBalancer frontend required = [] forbidden = [ 'app_gateway_subnet_address_prefix', 'application_gateway', 'app_gateway_sku', 'app_gateway_capacity' ] validate_parameter_set(namespace, required, forbidden, description='network balancer: load balancer') if namespace.load_balancer: if check_existence(namespace.load_balancer, namespace.resource_group_name, 'Microsoft.Network', 'loadBalancers'): namespace.load_balancer_type = 'existing' namespace.backend_pool_name = namespace.backend_pool_name or \ _get_default_address_pool(namespace.resource_group_name, namespace.load_balancer, 'load_balancers') logger.debug("using specified existing load balancer '%s'", namespace.load_balancer) else: namespace.load_balancer_type = 'new' logger.debug( "load balancer '%s' not found. It will be created.", namespace.load_balancer) elif namespace.load_balancer == '': namespace.load_balancer_type = None logger.debug('no load balancer will be used') elif namespace.load_balancer is None: namespace.load_balancer_type = 'new' logger.debug('new load balancer will be created')
def _validate_vm_create_storage_profile(namespace, for_scale_set=False): # use minimal parameters to resolve the expected storage profile if getattr(namespace, 'attach_os_disk', None) and not namespace.image: if namespace.use_unmanaged_disk: # STORAGE PROFILE #3 namespace.storage_profile = StorageProfile.SASpecializedOSDisk else: # STORAGE PROFILE #6 namespace.storage_profile = StorageProfile.ManagedSpecializedOSDisk elif namespace.image and not getattr(namespace, 'attach_os_disk', None): image_type = _parse_image_argument(namespace) if image_type == 'uri': # STORAGE PROFILE #2 namespace.storage_profile = StorageProfile.SACustomImage elif image_type == 'image_id': # STORAGE PROFILE #5 namespace.storage_profile = StorageProfile.ManagedCustomImage elif image_type == 'urn': if namespace.use_unmanaged_disk: # STORAGE PROFILE #1 namespace.storage_profile = StorageProfile.SAPirImage else: # STORAGE PROFILE #4 namespace.storage_profile = StorageProfile.ManagedPirImage else: raise CLIError('Unrecognized image type: {}'.format(image_type)) else: # did not specify image XOR attach-os-disk raise CLIError( 'incorrect usage: --image IMAGE | --attach-os-disk DISK') auth_params = [ 'admin_password', 'admin_username', 'authentication_type', 'generate_ssh_keys', 'ssh_dest_key_path', 'ssh_key_value' ] # perform parameter validation for the specific storage profile # start with the required/forbidden parameters for VM if namespace.storage_profile == StorageProfile.ManagedPirImage: required = ['image'] forbidden = [ 'os_type', 'attach_os_disk', 'storage_account', 'storage_container_name', 'use_unmanaged_disk' ] if for_scale_set: forbidden.append('os_disk_name') _validate_managed_disk_sku(namespace.storage_sku) elif namespace.storage_profile == StorageProfile.ManagedCustomImage: required = ['image'] forbidden = [ 'os_type', 'attach_os_disk', 'storage_account', 'storage_container_name', 'use_unmanaged_disk' ] if for_scale_set: forbidden.append('os_disk_name') _validate_managed_disk_sku(namespace.storage_sku) elif namespace.storage_profile == StorageProfile.ManagedSpecializedOSDisk: required = ['os_type', 'attach_os_disk'] forbidden = [ 'os_disk_name', 'os_caching', 'storage_account', 'storage_container_name', 'use_unmanaged_disk', 'storage_sku' ] + auth_params _validate_managed_disk_sku(namespace.storage_sku) elif namespace.storage_profile == StorageProfile.SAPirImage: required = ['image', 'use_unmanaged_disk'] forbidden = [ 'os_type', 'data_caching', 'attach_os_disk', 'data_disk_sizes_gb' ] elif namespace.storage_profile == StorageProfile.SACustomImage: required = ['image', 'os_type', 'use_unmanaged_disk'] forbidden = ['attach_os_disk', 'data_caching', 'data_disk_sizes_gb'] elif namespace.storage_profile == StorageProfile.SASpecializedOSDisk: required = ['os_type', 'attach_os_disk', 'use_unmanaged_disk'] forbidden = [ 'os_disk_name', 'os_caching', 'data_caching', 'image', 'storage_account', 'storage_container_name', 'data_disk_sizes_gb', 'storage_sku' ] + auth_params else: raise CLIError('Unrecognized storage profile: {}'.format( namespace.storage_profile)) logger.debug("storage profile '%s'", namespace.storage_profile) if for_scale_set: # VMSS lacks some parameters, so scrub these out props_to_remove = ['attach_os_disk', 'storage_account'] for prop in props_to_remove: if prop in required: required.remove(prop) if prop in forbidden: forbidden.remove(prop) # set default storage SKU if not provided and using an image based OS if not namespace.storage_sku and namespace.storage_profile in [StorageProfile.SAPirImage, StorageProfile.SACustomImage]: # pylint: disable=line-too-long namespace.storage_sku = 'Standard_LRS' if for_scale_set else 'Premium_LRS' # Now verify that the status of required and forbidden parameters validate_parameter_set(namespace, required, forbidden, description='storage profile: {}:'.format( _get_storage_profile_description( namespace.storage_profile))) if namespace.storage_profile == StorageProfile.ManagedCustomImage: # extract additional information from a managed custom image res = parse_resource_id(namespace.image) compute_client = _compute_client_factory() image_info = compute_client.images.get(res['resource_group'], res['name']) # pylint: disable=no-member namespace.os_type = image_info.storage_profile.os_disk.os_type.value namespace.image_data_disks = image_info.storage_profile.data_disks elif namespace.storage_profile == StorageProfile.ManagedSpecializedOSDisk: # accept disk name or ID namespace.attach_os_disk = _get_resource_id( namespace.attach_os_disk, namespace.resource_group_name, 'disks', 'Microsoft.Compute') if getattr(namespace, 'attach_data_disks', None): if not namespace.use_unmanaged_disk: namespace.attach_data_disks = [ _get_resource_id(d, namespace.resource_group_name, 'disks', 'Microsoft.Compute') for d in namespace.attach_data_disks ] if not namespace.os_type: namespace.os_type = 'windows' if 'windows' in namespace.os_offer.lower( ) else 'linux'
def _validate_vmss_create_load_balancer_or_app_gateway(namespace): INSTANCE_THRESHOLD = _get_vmss_create_instance_threshold() # convert the single_placement_group to boolean for simpler logic beyond if namespace.single_placement_group is None: namespace.single_placement_group = namespace.instance_count <= INSTANCE_THRESHOLD else: namespace.single_placement_group = (namespace.single_placement_group == 'true') if not namespace.single_placement_group and namespace.load_balancer: raise CLIError( '--load-balancer is not applicable when --single-placement-group is turned off.') if namespace.load_balancer and namespace.application_gateway: raise CLIError('incorrect usage: --load-balancer NAME_OR_ID | ' '--application-gateway NAME_OR_ID') if namespace.instance_count > INSTANCE_THRESHOLD and namespace.load_balancer: raise CLIError( '--load-balancer cannot be used with --instance_count is > {}'.format( INSTANCE_THRESHOLD)) # Resolve the type of balancer (if any) being used balancer_type = 'None' if namespace.load_balancer is None and namespace.application_gateway is None: # use defaulting rules to determine balancer_type = 'loadBalancer' if namespace.instance_count <= INSTANCE_THRESHOLD \ else 'applicationGateway' logger.debug("defaulting to '%s' because instance count <= %s", balancer_type, INSTANCE_THRESHOLD) elif namespace.load_balancer: balancer_type = 'loadBalancer' elif namespace.application_gateway: balancer_type = 'applicationGateway' if balancer_type == 'applicationGateway': if namespace.application_gateway: client = get_network_client().application_gateways try: rg = parse_resource_id(namespace.application_gateway).get( 'resource_group', namespace.resource_group_name) ag_name = parse_resource_id(namespace.application_gateway)['name'] client.get(rg, ag_name) namespace.app_gateway_type = 'existing' namespace.backend_pool_name = namespace.backend_pool_name or \ _get_default_address_pool(rg, ag_name, 'application_gateways') logger.debug("using specified existing application gateway '%s'", namespace.application_gateway) except CloudError: namespace.app_gateway_type = 'new' logger.debug("application gateway '%s' not found. It will be created.", namespace.application_gateway) elif namespace.application_gateway == '': namespace.app_gateway_type = None logger.debug('no application gateway will be used') elif namespace.application_gateway is None: namespace.app_gateway_type = 'new' logger.debug('new application gateway will be created') # AppGateway frontend required = [] if namespace.app_gateway_type == 'new': required.append('app_gateway_sku') required.append('app_gateway_capacity') if namespace.vnet_type != 'new': required.append('app_gateway_subnet_address_prefix') elif namespace.app_gateway_type == 'existing': required.append('backend_pool_name') forbidden = ['nat_pool_name', 'load_balancer', 'health_probe'] validate_parameter_set(namespace, required, forbidden, description='network balancer: application gateway') elif balancer_type == 'loadBalancer': # LoadBalancer frontend required = [] forbidden = ['app_gateway_subnet_address_prefix', 'application_gateway', 'app_gateway_sku', 'app_gateway_capacity'] validate_parameter_set(namespace, required, forbidden, description='network balancer: load balancer') if namespace.load_balancer: rg = parse_resource_id(namespace.load_balancer).get('resource_group', namespace.resource_group_name) lb_name = parse_resource_id(namespace.load_balancer)['name'] lb = get_network_lb(namespace.resource_group_name, lb_name) if lb: namespace.load_balancer_type = 'existing' namespace.backend_pool_name = namespace.backend_pool_name or \ _get_default_address_pool(rg, lb_name, 'load_balancers') if not namespace.nat_pool_name: if len(lb.inbound_nat_pools) > 1: raise CLIError("Multiple possible values found for '{0}': {1}\nSpecify '{0}' explicitly.".format( # pylint: disable=line-too-long '--nat-pool-name', ', '.join([n.name for n in lb.inbound_nat_pools]))) elif not lb.inbound_nat_pools: # Associated scaleset will be missing ssh/rdp, so warn here. logger.warning("No inbound nat pool was configured on '{}'".format(namespace.load_balancer)) else: namespace.nat_pool_name = lb.inbound_nat_pools[0].name logger.debug("using specified existing load balancer '%s'", namespace.load_balancer) else: namespace.load_balancer_type = 'new' logger.debug("load balancer '%s' not found. It will be created.", namespace.load_balancer) elif namespace.load_balancer == '': namespace.load_balancer_type = None logger.debug('no load balancer will be used') elif namespace.load_balancer is None: namespace.load_balancer_type = 'new' logger.debug('new load balancer will be created')
def _validate_vm_create_storage_profile(namespace, for_scale_set=False): # use minimal parameters to resolve the expected storage profile if getattr(namespace, 'attach_os_disk', None) and not namespace.image: if namespace.use_unmanaged_disk: # STORAGE PROFILE #3 namespace.storage_profile = StorageProfile.SASpecializedOSDisk else: # STORAGE PROFILE #6 namespace.storage_profile = StorageProfile.ManagedSpecializedOSDisk elif namespace.image and not getattr(namespace, 'attach_os_disk', None): image_type = _parse_image_argument(namespace) if image_type == 'uri': # STORAGE PROFILE #2 namespace.storage_profile = StorageProfile.SACustomImage elif image_type == 'image_id': # STORAGE PROFILE #5 namespace.storage_profile = StorageProfile.ManagedCustomImage elif image_type == 'urn': if namespace.use_unmanaged_disk: # STORAGE PROFILE #1 namespace.storage_profile = StorageProfile.SAPirImage else: # STORAGE PROFILE #4 namespace.storage_profile = StorageProfile.ManagedPirImage else: raise CLIError('Unrecognized image type: {}'.format(image_type)) else: # did not specify image XOR attach-os-disk raise CLIError('incorrect usage: --image IMAGE | --attach-os-disk DISK') auth_params = ['admin_password', 'admin_username', 'authentication_type', 'generate_ssh_keys', 'ssh_dest_key_path', 'ssh_key_value'] # perform parameter validation for the specific storage profile # start with the required/forbidden parameters for VM if namespace.storage_profile == StorageProfile.ManagedPirImage: required = ['image'] forbidden = ['os_type', 'attach_os_disk', 'storage_account', 'storage_container_name', 'use_unmanaged_disk'] if for_scale_set: forbidden.append('os_disk_name') _validate_managed_disk_sku(namespace.storage_sku) elif namespace.storage_profile == StorageProfile.ManagedCustomImage: required = ['image'] forbidden = ['os_type', 'attach_os_disk', 'storage_account', 'storage_container_name', 'use_unmanaged_disk'] if for_scale_set: forbidden.append('os_disk_name') _validate_managed_disk_sku(namespace.storage_sku) elif namespace.storage_profile == StorageProfile.ManagedSpecializedOSDisk: required = ['os_type', 'attach_os_disk'] forbidden = ['os_disk_name', 'os_caching', 'storage_account', 'storage_container_name', 'use_unmanaged_disk', 'storage_sku'] + auth_params _validate_managed_disk_sku(namespace.storage_sku) elif namespace.storage_profile == StorageProfile.SAPirImage: required = ['image', 'use_unmanaged_disk'] forbidden = ['os_type', 'data_caching', 'attach_os_disk', 'data_disk_sizes_gb'] elif namespace.storage_profile == StorageProfile.SACustomImage: required = ['image', 'os_type', 'use_unmanaged_disk'] forbidden = ['attach_os_disk', 'data_caching', 'data_disk_sizes_gb'] elif namespace.storage_profile == StorageProfile.SASpecializedOSDisk: required = ['os_type', 'attach_os_disk', 'use_unmanaged_disk'] forbidden = ['os_disk_name', 'os_caching', 'data_caching', 'image', 'storage_account', 'storage_container_name', 'data_disk_sizes_gb', 'storage_sku'] + auth_params else: raise CLIError('Unrecognized storage profile: {}'.format(namespace.storage_profile)) logger.debug("storage profile '%s'", namespace.storage_profile) if for_scale_set: # VMSS lacks some parameters, so scrub these out props_to_remove = ['attach_os_disk', 'storage_account'] for prop in props_to_remove: if prop in required: required.remove(prop) if prop in forbidden: forbidden.remove(prop) # set default storage SKU if not provided and using an image based OS if not namespace.storage_sku and namespace.storage_profile in [StorageProfile.SAPirImage, StorageProfile.SACustomImage]: # pylint: disable=line-too-long namespace.storage_sku = 'Standard_LRS' if for_scale_set else 'Premium_LRS' # Now verify that the status of required and forbidden parameters validate_parameter_set( namespace, required, forbidden, description='storage profile: {}:'.format(_get_storage_profile_description(namespace.storage_profile))) if namespace.storage_profile == StorageProfile.ManagedCustomImage: # extract additional information from a managed custom image res = parse_resource_id(namespace.image) compute_client = _compute_client_factory() image_info = compute_client.images.get(res['resource_group'], res['name']) # pylint: disable=no-member namespace.os_type = image_info.storage_profile.os_disk.os_type.value namespace.image_data_disks = image_info.storage_profile.data_disks elif namespace.storage_profile == StorageProfile.ManagedSpecializedOSDisk: # accept disk name or ID namespace.attach_os_disk = _get_resource_id( namespace.attach_os_disk, namespace.resource_group_name, 'disks', 'Microsoft.Compute') if getattr(namespace, 'attach_data_disks', None): if not namespace.use_unmanaged_disk: namespace.attach_data_disks = [_get_resource_id(d, namespace.resource_group_name, 'disks', 'Microsoft.Compute') for d in namespace.attach_data_disks] if not namespace.os_type: namespace.os_type = 'windows' if 'windows' in namespace.os_offer.lower() else 'linux'
def _validate_vmss_create_load_balancer_or_app_gateway(namespace): INSTANCE_THRESHOLD = _get_vmss_create_instance_threshold() # convert the single_placement_group to boolean for simpler logic beyond if namespace.single_placement_group is None: namespace.single_placement_group = namespace.instance_count <= INSTANCE_THRESHOLD else: namespace.single_placement_group = (namespace.single_placement_group == 'true') if not namespace.single_placement_group and namespace.load_balancer: raise CLIError( '--load-balancer is not applicable when --single-placement-group is turned off.') if namespace.load_balancer and namespace.application_gateway: raise CLIError('incorrect usage: --load-balancer NAME_OR_ID | ' '--application-gateway NAME_OR_ID') if namespace.instance_count > INSTANCE_THRESHOLD and namespace.load_balancer: raise CLIError( '--load-balancer cannot be used with --instance_count is > {}'.format( INSTANCE_THRESHOLD)) # Resolve the type of balancer (if any) being used balancer_type = 'None' if namespace.load_balancer is None and namespace.application_gateway is None: # use defaulting rules to determine balancer_type = 'loadBalancer' if namespace.instance_count <= INSTANCE_THRESHOLD \ else 'applicationGateway' logger.debug("defaulting to '%s' because instance count <= %s", balancer_type, INSTANCE_THRESHOLD) elif namespace.load_balancer: balancer_type = 'loadBalancer' elif namespace.application_gateway: balancer_type = 'applicationGateway' if balancer_type == 'applicationGateway': if namespace.application_gateway: client = get_network_client().application_gateways try: rg = parse_resource_id(namespace.application_gateway).get( 'resource_group', namespace.resource_group_name) ag_name = parse_resource_id(namespace.application_gateway)['name'] client.get(rg, ag_name) namespace.app_gateway_type = 'existing' namespace.backend_pool_name = namespace.backend_pool_name or \ _get_default_address_pool(rg, ag_name, 'application_gateways') logger.debug("using specified existing application gateway '%s'", namespace.application_gateway) except CloudError: namespace.app_gateway_type = 'new' logger.debug("application gateway '%s' not found. It will be created.", namespace.application_gateway) elif namespace.application_gateway == '': namespace.app_gateway_type = None logger.debug('no application gateway will be used') elif namespace.application_gateway is None: namespace.app_gateway_type = 'new' logger.debug('new application gateway will be created') # AppGateway frontend required = [] if namespace.app_gateway_type == 'new': required.append('app_gateway_sku') required.append('app_gateway_capacity') if namespace.vnet_type != 'new': required.append('app_gateway_subnet_address_prefix') elif namespace.app_gateway_type == 'existing': required.append('backend_pool_name') forbidden = ['nat_pool_name', 'load_balancer'] validate_parameter_set(namespace, required, forbidden, description='network balancer: application gateway') elif balancer_type == 'loadBalancer': # LoadBalancer frontend required = [] forbidden = ['app_gateway_subnet_address_prefix', 'application_gateway', 'app_gateway_sku', 'app_gateway_capacity'] validate_parameter_set(namespace, required, forbidden, description='network balancer: load balancer') if namespace.load_balancer: rg = parse_resource_id(namespace.load_balancer).get('resource_group', namespace.resource_group_name) lb_name = parse_resource_id(namespace.load_balancer)['name'] if check_existence(lb_name, rg, 'Microsoft.Network', 'loadBalancers'): namespace.load_balancer_type = 'existing' namespace.backend_pool_name = namespace.backend_pool_name or \ _get_default_address_pool(rg, lb_name, 'load_balancers') logger.debug("using specified existing load balancer '%s'", namespace.load_balancer) else: namespace.load_balancer_type = 'new' logger.debug("load balancer '%s' not found. It will be created.", namespace.load_balancer) elif namespace.load_balancer == '': namespace.load_balancer_type = None logger.debug('no load balancer will be used') elif namespace.load_balancer is None: namespace.load_balancer_type = 'new' logger.debug('new load balancer will be created')