def process_ag_url_path_map_rule_create_namespace(namespace): # pylint: disable=unused-argument if namespace.address_pool and not is_valid_resource_id(namespace.address_pool): namespace.address_pool = _generate_ag_subproperty_id( namespace, 'backendAddressPools', namespace.address_pool) if namespace.http_settings and not is_valid_resource_id(namespace.http_settings): namespace.http_settings = _generate_ag_subproperty_id( namespace, 'backendHttpSettingsCollection', namespace.http_settings)
def test_resource_id_simple(self): rg = 'lbrg' lb = 'mylb' namespace = 'Microsoft.Network' rtype = 'loadBalancers' sub = '00000000-0000-0000-0000-000000000000' result = resource_id(resource_group=rg, name=lb, namespace=namespace, type=rtype, subscription=sub) expected = '/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/lbrg/providers/Microsoft.Network/loadBalancers/mylb' self.assertTrue(is_valid_resource_id(expected)) self.assertTrue(is_valid_resource_id(result)) self.assertEqual(result, expected)
def process_ag_listener_create_namespace(namespace): # pylint: disable=unused-argument if not is_valid_resource_id(namespace.frontend_ip): namespace.frontend_ip = _generate_ag_subproperty_id( namespace, 'frontendIpConfigurations', namespace.frontend_ip) if not is_valid_resource_id(namespace.frontend_port): namespace.frontend_port = _generate_ag_subproperty_id( namespace, 'frontendPorts', namespace.frontend_port) if not is_valid_resource_id(namespace.ssl_cert): namespace.ssl_cert = _generate_ag_subproperty_id( namespace, 'sslCertificates', namespace.ssl_cert)
def test_resource_id_complex(self): rg = 'lbrg' lb = 'mylb' namespace = 'Microsoft.Network' rtype = 'loadBalancers' bep = 'mybep' bep_type = 'backendAddressPools' sub = '00000000-0000-0000-0000-000000000000' result = resource_id(name=lb, resource_group=rg, namespace=namespace, type=rtype, subscription=sub, child_type=bep_type, child_name=bep) expected = '/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/lbrg/providers/Microsoft.Network/loadBalancers/mylb/backendAddressPools/mybep' self.assertTrue(is_valid_resource_id(expected)) self.assertTrue(is_valid_resource_id(result)) self.assertEqual(result, expected)
def handle_folding(namespace): base_name_val = getattr(namespace, base_name) type_field_val = getattr(namespace, type_field) parent_name_val = getattr(namespace, parent_name) if parent_name else None if base_name_val is None or type_field_val is not None: # Either no name was specified, or the user specified the type of resource # (i.e. new/existing/none) pass elif base_name_val in ('', '""', "''"): # An empty name specified - that means that we are neither referencing an existing # field, or the name is set to an empty string. We check for all types of quotes # so scripts can run cross-platform. if not allow_none: raise CLIError('Field {} cannot be none.'.format(make_camel_case(base_name))) setattr(namespace, type_field, none_flag_value) setattr(namespace, base_name, None) else: from azure.cli.commands.client_factory import get_subscription_id has_parent = parent_name is not None and parent_type is not None if is_valid_resource_id(base_name_val): resource_id_parts = parse_resource_id(base_name_val) elif has_parent: resource_id_parts = dict( name=parent_name_val, resource_group=namespace.resource_group_name, namespace=parent_type.split('/')[0], type=parent_type.split('/')[1], subscription=get_subscription_id(), child_name=base_name_val, child_type=resource_type) else: resource_id_parts = dict( name=base_name_val, resource_group=namespace.resource_group_name, namespace=resource_type.split('/')[0], type=resource_type.split('/')[1], subscription=get_subscription_id()) if resource_exists(**resource_id_parts): setattr(namespace, type_field, existing_id_flag_value) setattr(namespace, base_name, resource_id(**resource_id_parts)) elif is_valid_resource_id(base_name_val): raise CLIError('ID {} does not exist. Please specify ' 'a name to create a new resource.'.format( resource_id(**resource_id_parts))) else: setattr(namespace, type_field, new_flag_value)
def _generate_lb_id_list_from_names_or_ids(namespace, prop, child_type): raw = getattr(namespace, prop) if not raw: return raw = raw if isinstance(raw, list) else [raw] result = [] subscription = get_subscription_id() lb_name = namespace.load_balancer_name for item in raw: if is_valid_resource_id(item): result.append({'id': item}) else: if not lb_name: raise CLIError( 'Unable to process {}. Please supply a well-formed ID or ' '--lb-name.'.format(item)) else: result.append({ 'id': _generate_lb_subproperty_id( subscription=subscription, resource_group=namespace.resource_group_name, load_balancer_name=lb_name, child_type=child_type, child_name=item) }) setattr(namespace, prop, result)
def validate_subnet_name_or_id(namespace): """ Validates a subnet ID or, if a name is provided, formats it as an ID. """ if namespace.virtual_network_name is None and namespace.subnet is None: return if namespace.subnet == '': return # error if vnet-name is provided without subnet if namespace.virtual_network_name and not namespace.subnet: raise CLIError( 'You must specify --subnet name when using --vnet-name.') # determine if subnet is name or ID is_id = is_valid_resource_id(namespace.subnet) # error if vnet-name is provided along with a subnet ID if is_id and namespace.virtual_network_name: raise argparse.ArgumentError( None, 'Please omit --vnet-name when specifying a subnet ID') elif not is_id and not namespace.virtual_network_name: raise argparse.ArgumentError( None, 'Please specify --vnet-name when specifying a subnet name') if not is_id: namespace.subnet = resource_id( subscription=get_subscription_id(), resource_group=namespace.resource_group_name, namespace='Microsoft.Network', type='virtualNetworks', name=namespace.virtual_network_name, child_type='subnets', child_name=namespace.subnet)
def move_resource(ids, destination_group, destination_subscription_id=None): '''Moves resources from one resource group to another(can be under different subscription) :param ids: the space separated resource ids to be moved :param destination_group: the destination resource group name :param destination_subscription_id: the destination subscription identifier ''' from azure.cli.commands.arm import parse_resource_id, is_valid_resource_id, resource_id #verify all resource ids are valid and under the same group resources = [] for i in ids: if is_valid_resource_id(i): resources.append(parse_resource_id(i)) else: raise CLIError('Invalid id "{}", as it has no group or subscription field'.format(i)) if len(set([r['subscription'] for r in resources])) > 1: raise CLIError('All resources should be under the same subscription') if len(set([r['resource_group'] for r in resources])) > 1: raise CLIError('All resources should be under the same group') rcf = _resource_client_factory() target = resource_id(subscription=(destination_subscription_id or rcf.config.subscription_id), resource_group=destination_group) return rcf.resources.move_resources(resources[0]['resource_group'], ids, target)
def move_resource(ids, destination_group, destination_subscription_id=None): '''Moves resources from one resource group to another(can be under different subscription) :param ids: the space separated resource ids to be moved :param destination_group: the destination resource group name :param destination_subscription_id: the destination subscription identifier ''' from azure.cli.commands.arm import resource_id #verify all resource ids are valid and under the same group resources = [] for i in ids: if is_valid_resource_id(i): resources.append(parse_resource_id(i)) else: raise CLIError('Invalid id "{}", as it has no group or subscription field'.format(i)) if len(set([r['subscription'] for r in resources])) > 1: raise CLIError('All resources should be under the same subscription') if len(set([r['resource_group'] for r in resources])) > 1: raise CLIError('All resources should be under the same group') rcf = _resource_client_factory() target = resource_id(subscription=(destination_subscription_id or rcf.config.subscription_id), resource_group=destination_group) return rcf.resources.move_resources(resources[0]['resource_group'], ids, target)
def validate_subnet_name_or_id(namespace): """ Validates a subnet ID or, if a name is provided, formats it as an ID. """ if namespace.virtual_network_name is None and namespace.subnet is None: return if namespace.subnet == '': return # error if vnet-name is provided without subnet if namespace.virtual_network_name and not namespace.subnet: raise CLIError('You must specify --subnet name when using --vnet-name.') # determine if subnet is name or ID is_id = is_valid_resource_id(namespace.subnet) # error if vnet-name is provided along with a subnet ID if is_id and namespace.virtual_network_name: raise argparse.ArgumentError(None, 'Please omit --vnet-name when specifying a subnet ID') elif not is_id and not namespace.virtual_network_name: raise argparse.ArgumentError(None, 'Please specify --vnet-name when specifying a subnet name') if not is_id: namespace.subnet = resource_id( subscription=get_subscription_id(), resource_group=namespace.resource_group_name, namespace='Microsoft.Network', type='virtualNetworks', name=namespace.virtual_network_name, child_type='subnets', child_name=namespace.subnet)
def handle_folding(namespace): base_name_val = getattr(namespace, base_name) type_field_val = getattr(namespace, type_field) parent_name_val = getattr(namespace, parent_name) if parent_name else None if base_name_val is None or type_field_val is not None: # Either no name was specified, or the user specified the type of resource # (i.e. new/existing/none) pass elif base_name_val == '': # An empty name specified - that means that we are neither referencing an existing # field, or the name is set to an empty string setattr(namespace, type_field, none_flag_value) else: from azure.cli.commands.client_factory import get_subscription_id has_parent = parent_name is not None and parent_type is not None if is_valid_resource_id(base_name_val): resource_id_parts = parse_resource_id(base_name_val) elif has_parent: resource_id_parts = dict( name=parent_name_val, resource_group=namespace.resource_group_name, namespace=parent_type.split('/')[0], type=parent_type.split('/')[1], subscription=get_subscription_id(), child_name=base_name_val, child_type=resource_type) else: resource_id_parts = dict( name=base_name_val, resource_group=namespace.resource_group_name, namespace=resource_type.split('/')[0], type=resource_type.split('/')[1], subscription=get_subscription_id()) if resource_exists(**resource_id_parts): setattr(namespace, type_field, existing_id_flag_value) setattr(namespace, base_name, resource_id(**resource_id_parts)) elif is_valid_resource_id(base_name_val): raise CLIError('ID {} does not exist. Please specify ' 'a name to create a new resource.'.format( resource_id(**resource_id_parts))) else: setattr(namespace, type_field, new_flag_value)
def validate_nsg_name_or_id(namespace): """ Validates a NSG ID or, if a name is provided, formats it as an ID. """ if namespace.network_security_group: # determine if network_security_group is name or ID is_id = is_valid_resource_id(namespace.network_security_group) if not is_id: namespace.network_security_group = resource_id( subscription=get_subscription_id(), resource_group=namespace.resource_group_name, namespace='Microsoft.Network', type='networkSecurityGroups', name=namespace.network_security_group)
def validate_public_ip_name_or_id(namespace): """ Validates a public IP ID or, if a name is provided, formats it as an ID. """ if namespace.public_ip_address: # determine if public_ip_address is name or ID is_id = is_valid_resource_id(namespace.public_ip_address) if not is_id: namespace.public_ip_address = resource_id( subscription=get_subscription_id(), resource_group=namespace.resource_group_name, namespace='Microsoft.Network', type='publicIPAddresses', name=namespace.public_ip_address)
def validate_address_pool_name_or_id(namespace): pool_name = namespace.backend_address_pool lb_name = namespace.load_balancer_name if is_valid_resource_id(pool_name): if lb_name: raise CLIError('Please omit --lb-name when specifying an address pool ID.') else: if not lb_name: raise CLIError('Please specify --lb-name when specifying an address pool name.') namespace.backend_address_pool = _generate_lb_subproperty_id( namespace, 'backendAddressPools', pool_name)
def validate_inbound_nat_rule_name_or_id(namespace): rule_name = namespace.inbound_nat_rule lb_name = namespace.load_balancer_name if is_valid_resource_id(rule_name): if lb_name: raise CLIError('Please omit --lb-name when specifying an inbound NAT rule ID.') else: if not lb_name: raise CLIError('Please specify --lb-name when specifying an inbound NAT rule name.') namespace.inbound_nat_rule = _generate_lb_subproperty_id( namespace, 'inboundNatRules', rule_name)
def _generate_lb_id_list_from_names_or_ids(namespace, prop, child_type): raw = getattr(namespace, prop) if not raw: return raw = raw if isinstance(raw, list) else [raw] result = [] for item in raw: if is_valid_resource_id(item): result.append({'id': item}) else: if not namespace.load_balancer_name: raise CLIError('Unable to process {}. Please supply a well-formed ID or ' '--lb-name.'.format(item)) else: result.append({'id': _generate_lb_subproperty_id( namespace, child_type, item)}) setattr(namespace, prop, result)
def validate_address_pool_name_or_id(namespace): pool_name = namespace.backend_address_pool lb_name = namespace.load_balancer_name if is_valid_resource_id(pool_name): if lb_name: raise CLIError( 'Please omit --lb-name when specifying an address pool ID.') else: if not lb_name: raise CLIError( 'Please specify --lb-name when specifying an address pool name.' ) namespace.backend_address_pool = _generate_lb_subproperty_id( resource_group=namespace.resource_group_name, load_balancer_name=lb_name, child_type='backendAddressPools', child_name=pool_name)
def validate_inbound_nat_rule_name_or_id(namespace): rule_name = namespace.inbound_nat_rule lb_name = namespace.load_balancer_name if is_valid_resource_id(rule_name): if lb_name: raise CLIError( 'Please omit --lb-name when specifying an inbound NAT rule ID.' ) else: if not lb_name: raise CLIError( 'Please specify --lb-name when specifying an inbound NAT rule name.' ) namespace.inbound_nat_rule = _generate_lb_subproperty_id( resource_group=namespace.resource_group_name, load_balancer_name=lb_name, child_type='inboundNatRules', child_name=rule_name)
def process_ag_http_settings_create_namespace(namespace): # pylint: disable=unused-argument if not is_valid_resource_id(namespace.probe): namespace.probe = _generate_ag_subproperty_id( namespace, 'probes', namespace.probe)
def _resolve_policy_id(policy, client): policy_id = policy if not is_valid_resource_id(policy): policy_def = client.policy_definitions.get(policy) policy_id = policy_def.id return policy_id
authentication_type = CliArgumentType( choices=['ssh', 'password'], default=None, help='Password or SSH public key authentication. Defaults to password for Windows and SSH public key for Linux.', type=str.lower ) nsg_rule_type = CliArgumentType( choices=['RDP', 'SSH'], default=None, help='Network security group rule to create. Defaults open ports for allowing RDP on Windows and allowing SSH on Linux.', type=str.upper ) register_cli_argument('vm create', 'network_interface_type', help=argparse.SUPPRESS) register_cli_argument('vm create', 'network_interface_ids', options_list=('--nics',), nargs='+', help='Names or IDs of existing NICs to reference. The first NIC will be the primary NIC.', type=lambda val: val if (not '/' in val or is_valid_resource_id(val, ValueError)) else '', validator=_handle_vm_nics) register_cli_argument('vm create', 'name', name_arg_type, validator=_resource_not_exists('Microsoft.Compute/virtualMachines')) register_cli_argument('vmss create', 'name', name_arg_type, validator=_resource_not_exists('Microsoft.Compute/virtualMachineScaleSets')) register_cli_argument('vmss', 'vm_scale_set_name', name_arg_type, help='scale set name') register_cli_argument('vmss', 'instance_ids', help='Space separated ids such as "0 2 3", or use "*" for all instances') for scope in ['vm create', 'vmss create']: register_cli_argument(scope, 'location', CliArgumentType(completer=get_location_completion_list)) register_cli_argument(scope, 'custom_os_disk_uri', CliArgumentType(help=argparse.SUPPRESS)) register_cli_argument(scope, 'os_disk_type', CliArgumentType(help=argparse.SUPPRESS)) register_cli_argument(scope, 'os_disk_name', CliArgumentType(validator=_os_disk_default)) register_cli_argument(scope, 'overprovision', CliArgumentType(action='store_false', default=None, options_list=('--disable-overprovision',))) register_cli_argument(scope, 'upgrade_policy_mode', CliArgumentType(choices=choices_upgrade_mode, help=None, type=str.lower))
help= 'Network security group rule to create. Defaults open ports for allowing RDP on Windows and allowing SSH on Linux.', type=str.upper) register_cli_argument('vm create', 'network_interface_type', help=argparse.SUPPRESS) register_cli_argument( 'vm create', 'network_interface_ids', options_list=('--nics', ), nargs='+', help= 'Names or IDs of existing NICs to reference. The first NIC will be the primary NIC.', type=lambda val: val if (not '/' in val or is_valid_resource_id(val, ValueError)) else '', validator=_handle_vm_nics) register_cli_argument( 'vm create', 'name', name_arg_type, validator=_resource_not_exists('Microsoft.Compute/virtualMachines')) register_cli_argument('vmss create', 'name', name_arg_type, validator=_resource_not_exists( 'Microsoft.Compute/virtualMachineScaleSets')) register_cli_argument('vmss', 'vm_scale_set_name', name_arg_type,