def create_probe(ctx, **_): """Uses an existing, or creates a new, Load Balancer Probe""" # Check if invalid external resource if ctx.node.properties.get('use_external_resource', False) and \ not ctx.node.properties.get('name'): raise cfy_exc.NonRecoverableError( '"use_external_resource" specified without a resource "name"') # Generate a name if it doesn't exist azure_config = ctx.node.properties.get('azure_config') if not azure_config.get("subscription_id"): azure_config = ctx.node.properties.get('client_config') else: ctx.logger.warn("azure_config is deprecated please use client_config, " "in later version it will be removed") resource_group_name = utils.get_resource_group(ctx) load_balancer_name = ctx.node.properties.get('load_balancer_name') or \ utils.get_resource_name_ref(constants.REL_CONTAINED_IN_LB, 'load_balancer_name', _ctx=ctx) load_balancer = LoadBalancer(azure_config, ctx.logger) probe_name = ctx.node.properties.get('name') probe_name = \ get_unique_lb_prop_name(load_balancer, resource_group_name, load_balancer_name, "probes", probe_name) ctx.instance.runtime_properties['name'] = probe_name # Get an interface to the Load Balancer lb_rel = utils.get_relationship_by_type( ctx.instance.relationships, constants.REL_CONTAINED_IN_LB) lb_name = utils.get_resource_name(lb_rel.target) # Get the existing probes lb_data = load_balancer.get(resource_group_name, lb_name) lb_probes = lb_data.get('probes', list()) lb_probes.append({ 'name': probe_name, }) lb_probes = \ utils.handle_resource_config_params(lb_probes, ctx.node.properties.get( 'resource_config', {})) # Update the Load Balancer with the new probe lb_params = { 'probes': lb_probes } # clean empty values from params lb_params = \ utils.cleanup_empty_params(lb_params) try: result = load_balancer.create_or_update(resource_group_name, lb_name, lb_params) for item in result.get("probes"): if item.get("name") == probe_name: ctx.instance.runtime_properties['resource_id'] = item.get("id") ctx.instance.runtime_properties['resource'] = item except CloudError as cr: raise cfy_exc.NonRecoverableError( "create probe '{0}' " "failed with this error : {1}".format(probe_name, cr.message) )
def handle_credentials(self, azure_config): """ Gets any Azure API access information from the current node properties or a provider context file created during manager bootstrapping. :returns: Azure credentials and access information :rtype: dict """ def get_credentials_from_file(config_path=constants.CONFIG_PATH): """ Gets Azure API access information from the provider context config file :returns: Azure credentials and access information :rtype: dict """ cred_keys = [ 'client_id', 'client_secret', 'subscription_id', 'tenant_id', 'endpoint_resource', 'endpoint_verify', 'endpoints_resource_manager', 'endpoints_active_directory', 'certificate', 'thumbprint', 'cloud_environment' ] config = SafeConfigParser() config.read(config_path) return {k: config.get('Credentials', k) for k in cred_keys} f_creds = dict() f_config_path = environ.get(constants.CONFIG_PATH_ENV_VAR_NAME, constants.CONFIG_PATH) if path.exists(f_config_path): f_creds = get_credentials_from_file(f_config_path) creds = utils.dict_update(f_creds, azure_config) if 'endpoint_verify' not in creds: creds['endpoint_verify'] = True return utils.cleanup_empty_params(creds)
def create(ctx, **_): """Uses an existing, or creates a new, Storage Account""" # Generate a resource name (if needed) azure_config = ctx.node.properties.get('azure_config') if not azure_config.get("subscription_id"): azure_config = ctx.node.properties.get('client_config') else: ctx.logger.info("azure_config id deprecated please use client_config") name = utils.get_resource_name(ctx) resource_group_name = utils.get_resource_group(ctx) api_version = \ ctx.node.properties.get('api_version', constants.API_VER_STORAGE) storage_account = StorageAccount(azure_config, ctx.logger, api_version) sa_sku = ctx.node.properties.get('sku') sa_params = { 'location': ctx.node.properties.get('location'), 'tags': ctx.node.properties.get('tags'), 'account_type': ctx.node.properties.get('resource_config', {}).get('accountType'), 'network_rule_set': ctx.node.properties.get('resource_config', {}).get('networkAcls'), 'enable_https_traffic_only': ctx.node.properties.get('resource_config', {}).get('supportsHttpsTrafficOnly'), 'encryption': { 'services': ctx.node.properties.get('resource_config', {}).get('encryption'), 'key_source': ctx.node.properties.get('resource_config', {}).get('keySource'), } } if sa_sku: sa_params['sku'] = sa_sku # clean empty values from params sa_params = \ utils.cleanup_empty_params(sa_params) try: result = \ storage_account.create( resource_group_name, name, sa_params) except CloudError as cr: raise cfy_exc.NonRecoverableError( "create storage_account '{0}' " "failed with this error : {1}".format(name, cr.message)) ctx.instance.runtime_properties['resource_group'] = resource_group_name ctx.instance.runtime_properties['resource'] = result ctx.instance.runtime_properties['resource_id'] = result.get("id", "")
def create(ctx, **_): """Uses an existing, or creates a new, Public IP Address""" # Create a resource (if necessary) azure_config = ctx.node.properties.get('azure_config') if not azure_config.get("subscription_id"): azure_config = ctx.node.properties.get('client_config') else: ctx.logger.warn("azure_config is deprecated please use client_config, " "in later version it will be removed") name = utils.get_resource_name(ctx) resource_group_name = utils.get_resource_group(ctx) public_ip_address_params = { 'location': ctx.node.properties.get('location'), 'tags': ctx.node.properties.get('tags'), } public_ip_address_params = \ utils.handle_resource_config_params(public_ip_address_params, ctx.node.properties.get( 'resource_config', {})) # Special Case dnsSettings public_ip_address_params['dns_settings'] = { 'domain_name_label': public_ip_address_params.pop('domain_name_label', None), 'reverse_fqdn': public_ip_address_params.pop('reverse_fqdn', None) } api_version = \ ctx.node.properties.get('api_version', constants.API_VER_NETWORK) public_ip_address = PublicIPAddress(azure_config, ctx.logger, api_version) # clean empty values from params public_ip_address_params = \ utils.cleanup_empty_params(public_ip_address_params) try: result = \ public_ip_address.create_or_update( resource_group_name, name, public_ip_address_params) except CloudError as cr: raise cfy_exc.NonRecoverableError( "create public_ip_address '{0}' " "failed with this error : {1}".format(name, cr.message)) ctx.instance.runtime_properties['resource_group'] = resource_group_name ctx.instance.runtime_properties['resource'] = result ctx.instance.runtime_properties['resource_id'] = result.get("id", "")
def create(ctx, resource_config, **_): """Uses an existing, or creates a new, Virtual Machine Extension""" # Create a resource (if necessary) ctx.logger.warn('Azure customData implementation is dependent on ' 'Virtual Machine image support.') azure_config = ctx.node.properties.get('azure_config') if not azure_config.get("subscription_id"): azure_config = ctx.node.properties.get('client_config') else: ctx.logger.warn("azure_config is deprecated please use client_config, " "in later version it will be removed") name = utils.get_resource_name(ctx) resource_group_name = utils.get_resource_group(ctx) vm_name = ctx.node.properties['virtual_machine_name'] vm_extension_params = { 'location': ctx.node.properties.get('location'), 'tags': ctx.node.properties.get('tags'), 'publisher': resource_config.get('publisher'), 'virtual_machine_extension_type': resource_config.get('ext_type'), 'type_handler_version': resource_config.get('typeHandlerVersion'), 'settings': resource_config.get('settings'), } api_version = \ ctx.node.properties.get('api_version', constants.API_VER_COMPUTE) vm_extension = VirtualMachineExtension(azure_config, ctx.logger, api_version) # clean empty values from params vm_extension_params = \ utils.cleanup_empty_params(vm_extension_params) try: result = \ vm_extension.create_or_update(resource_group_name, vm_name, name, vm_extension_params) except CloudError as cr: raise cfy_exc.NonRecoverableError( "create vm_extension '{0}' " "failed with this error : {1}".format(name, cr.message)) ctx.instance.runtime_properties['resource_group'] = resource_group_name ctx.instance.runtime_properties['virtual_machine'] = vm_name ctx.instance.runtime_properties['resource'] = result ctx.instance.runtime_properties['resource_id'] = result.get("id", "")
def create(ctx, **_): """Uses an existing, or creates a new, Network Security Group""" # Create a resource (if necessary) azure_config = ctx.node.properties.get('azure_config') if not azure_config.get("subscription_id"): azure_config = ctx.node.properties.get('client_config') else: ctx.logger.warn("azure_config is deprecated please use client_config, " "in later version it will be removed") name = utils.get_resource_name(ctx) resource_group_name = utils.get_resource_group(ctx) nsg_params = { 'location': ctx.node.properties.get('location'), 'tags': ctx.node.properties.get('tags'), } nsg_params = \ utils.handle_resource_config_params(nsg_params, ctx.node.properties.get( 'resource_config', {})) api_version = \ ctx.node.properties.get('api_version', constants.API_VER_NETWORK) network_security_group = NetworkSecurityGroup(azure_config, ctx.logger, api_version) # clean empty values from params nsg_params = \ utils.cleanup_empty_params(nsg_params) try: result = \ network_security_group.create_or_update( resource_group_name, name, nsg_params) except CloudError as cr: raise cfy_exc.NonRecoverableError( "create network_security_group '{0}' " "failed with this error : {1}".format(name, cr.message)) ctx.instance.runtime_properties['resource_group'] = resource_group_name ctx.instance.runtime_properties['resource'] = result ctx.instance.runtime_properties['resource_id'] = result.get("id", "")
def create(ctx, **_): """Uses an existing, or creates a new, Availability Set""" azure_config = ctx.node.properties.get('azure_config') if not azure_config.get("subscription_id"): azure_config = ctx.node.properties.get('client_config') else: ctx.logger.warn("azure_config is deprecated please use client_config, " "in later version it will be removed") name = utils.get_resource_name(ctx) resource_group_name = utils.get_resource_group(ctx) resource_config = ctx.node.properties.get('resource_config') availability_set_conf = { 'location': ctx.node.properties.get('location'), 'tags': ctx.node.properties.get('tags'), } availability_set_conf = \ utils.handle_resource_config_params(availability_set_conf, resource_config) api_version = \ ctx.node.properties.get('api_version', constants.API_VER_COMPUTE) availability_set = AvailabilitySet(azure_config, ctx.logger, api_version) # clean empty values from params availability_set_conf = utils.cleanup_empty_params(availability_set_conf) try: result = \ availability_set.create_or_update(resource_group_name, name, availability_set_conf) except CloudError as cr: raise cfy_exc.NonRecoverableError( "create availability_set '{0}' " "failed with this error : {1}".format(name, cr.message) ) ctx.instance.runtime_properties['resource_group'] = resource_group_name ctx.instance.runtime_properties['resource'] = result ctx.instance.runtime_properties['resource_id'] = result.get("id", "")
def configure(ctx, **_): """Uses an existing, or creates a new, Load Balancer""" # Get the Frontend IP Configuration fe_ip_cfg = get_ip_configurations(rel=constants.REL_LB_CONNECTED_TO_IPC) ctx.logger.debug('fe_ip_cfg: {0}'.format(fe_ip_cfg)) if not len(fe_ip_cfg): raise cfy_exc.NonRecoverableError( 'At least 1 Frontend IP Configuration must be ' 'associated with the Load Balancer') # Remove the subnet if there's a public IP present for ip_cfg in fe_ip_cfg: if ip_cfg.get('public_ip_address'): if ip_cfg.get('subnet'): del ip_cfg['subnet'] # Create a resource (if necessary) azure_config = ctx.node.properties.get('azure_config') if not azure_config.get("subscription_id"): azure_config = ctx.node.properties.get('client_config') else: ctx.logger.warn("azure_config is deprecated please use client_config, " "in later version it will be removed") name = ctx.instance.runtime_properties.get('name') resource_group_name = utils.get_resource_group(ctx) api_version = \ ctx.node.properties.get('api_version', constants.API_VER_NETWORK) load_balancer = LoadBalancer(azure_config, ctx.logger, api_version) lb_params = { 'location': ctx.node.properties.get('location'), 'tags': ctx.node.properties.get('tags'), } lb_params = \ utils.handle_resource_config_params(lb_params, ctx.node.properties.get( 'resource_config', {})) lb_params = utils.dict_update( lb_params, { 'frontend_ip_configurations': fe_ip_cfg } ) # clean empty values from params lb_params = \ utils.cleanup_empty_params(lb_params) try: result = \ load_balancer.create_or_update(resource_group_name, name, lb_params) except CloudError as cr: raise cfy_exc.NonRecoverableError( "create load_balancer '{0}' " "failed with this error : {1}".format(name, cr.message) ) ctx.instance.runtime_properties['resource_group'] = resource_group_name ctx.instance.runtime_properties['resource'] = result ctx.instance.runtime_properties['resource_id'] = result.get("id", "") ctx.instance.runtime_properties['name'] = name for fe_ipc_data in result.get('frontend_ip_configurations', list()): ctx.instance.runtime_properties['ip'] = \ fe_ipc_data.get('private_ip_address') public_ip = \ fe_ipc_data.get('public_ip_address', {}).get('ip_address', None) if not public_ip: pip = PublicIPAddress(azure_config, ctx.logger) pip_name = \ ip_cfg.get('public_ip_address').get('id').rsplit('/', 1)[1] public_ip_data = pip.get(resource_group_name, pip_name) public_ip = public_ip_data.get("ip_address") ctx.instance.runtime_properties['public_ip'] = public_ip
def create_rule(ctx, **_): """Uses an existing, or creates a new, Load Balancer Rule""" # Check if invalid external resource if ctx.node.properties.get('use_external_resource', False) and \ not ctx.node.properties.get('name'): raise cfy_exc.NonRecoverableError( '"use_external_resource" specified without a resource "name"') # Generate a name if it doesn't exist azure_config = ctx.node.properties.get('azure_config') if not azure_config.get("subscription_id"): azure_config = ctx.node.properties.get('client_config') else: ctx.logger.warn("azure_config is deprecated please use client_config, " "in later version it will be removed") resource_group_name = utils.get_resource_group(ctx) load_balancer_name = ctx.node.properties.get('load_balancer_name') or \ utils.get_resource_name_ref(constants.REL_CONTAINED_IN_LB, 'load_balancer_name', _ctx=ctx) load_balancer = LoadBalancer(azure_config, ctx.logger) lb_rule_name = ctx.node.properties.get('name') lb_rule_name = \ get_unique_lb_prop_name(load_balancer, resource_group_name, load_balancer_name, "load_balancing_rules", lb_rule_name) ctx.instance.runtime_properties['name'] = lb_rule_name # Get an interface to the Load Balancer lb_rel = utils.get_relationship_by_type( ctx.instance.relationships, constants.REL_CONTAINED_IN_LB) lb_name = utils.get_resource_name(lb_rel.target) load_balancer = LoadBalancer(azure_config, ctx.logger) lb_data = load_balancer.get(resource_group_name, lb_name) # Get the Load Balancer Backend Pool/ Probe/ Frontend IP Configuration lb_be_pool_id = "" lb_probe_id = "" lb_fe_ipc_id = "" rel_pool_type = constants.REL_CONNECTED_TO_LB_BE_POOL rel_probe_type = constants.REL_CONNECTED_TO_LB_PROBE rel_fe_type = constants.REL_CONNECTED_TO_IPC for rel in ctx.instance.relationships: if isinstance(rel_pool_type, tuple): if any(x in rel.type_hierarchy for x in rel_pool_type): lb_be_pool_id = \ rel.target.instance.runtime_properties.get('resource_id') else: if rel_pool_type in rel.type_hierarchy: lb_be_pool_id = \ rel.target.instance.runtime_properties.get('resource_id') if isinstance(rel_probe_type, tuple): if any(x in rel.type_hierarchy for x in rel_probe_type): lb_probe_id = \ rel.target.instance.runtime_properties.get('resource_id') else: if constants.REL_CONNECTED_TO_LB_PROBE in rel.type_hierarchy: lb_probe_id = \ rel.target.instance.runtime_properties.get('resource_id') if isinstance(rel_fe_type, tuple): if any(x in rel.type_hierarchy for x in rel_fe_type): lb_fe_ipc_id = \ rel.target.instance.runtime_properties.get('resource_id') else: if constants.REL_CONNECTED_TO_IPC in rel.type_hierarchy: lb_fe_ipc_id = \ rel.target.instance.runtime_properties.get('resource_id') # Get the existing Load Balancer Rules lb_rules = lb_data.get('load_balancing_rules', list()) lb_rules.append({ 'name': lb_rule_name, 'frontend_ip_configuration': {'id': lb_fe_ipc_id}, 'backend_address_pool': {'id': lb_be_pool_id}, 'probe': {'id': lb_probe_id} }) # Update the Load Balancer with the new rule lb_params = { 'load_balancing_rules': lb_rules } # clean empty values from params lb_params = \ utils.cleanup_empty_params(lb_params) try: result = load_balancer.create_or_update(resource_group_name, lb_name, lb_params) for item in result.get("load_balancing_rules"): if item.get("name") == lb_rule_name: ctx.instance.runtime_properties['resource_id'] = item.get("id") ctx.instance.runtime_properties['resource'] = item except CloudError as cr: raise cfy_exc.NonRecoverableError( "create load_balancing_rules '{0}' " "failed with this error : {1}".format(lb_rule_name, cr.message) )
def configure(ctx, **_): """ Uses an existing, or creates a new, Network Interface Card .. warning:: The "configure" operation is actually the second half of the "create" operation. This is necessary since IP Configuration nodes are treated as separate, stand-alone types and must be "connected" to the NIC before it's actually created. The actual "create" operation simply assigns a UUID for the node and the "configure" operation creates the object """ # Create a resource (if necessary) azure_config = ctx.node.properties.get('azure_config') if not azure_config.get("subscription_id"): azure_config = ctx.node.properties.get('client_config') else: ctx.logger.warn("azure_config is deprecated please use client_config, " "in later version it will be removed") name = ctx.instance.runtime_properties.get('name') resource_group_name = utils.get_resource_group(ctx) api_version = \ ctx.node.properties.get('api_version', constants.API_VER_NETWORK) network_interface_card = NetworkInterfaceCard(azure_config, ctx.logger, api_version) nic_params = { 'location': ctx.node.properties.get('location'), 'tags': ctx.node.properties.get('tags'), 'primary': ctx.node.properties.get('primary'), } nic_params = \ utils.handle_resource_config_params(nic_params, ctx.node.properties.get( 'resource_config', {})) # Special Case network_security_group instead of networkSecurityGroups nic_params['network_security_group'] = \ nic_params.pop('network_security_groups', None) # clean empty values from params nic_params = \ utils.cleanup_empty_params(nic_params) nic_params = utils.dict_update( nic_params, { 'network_security_group': get_connected_nsg(ctx), 'ip_configurations': get_ip_configurations(ctx) }) # clean empty values from params nic_params = \ utils.cleanup_empty_params(nic_params) try: result = \ network_interface_card.create_or_update( resource_group_name, name, nic_params) except CloudError as cr: raise cfy_exc.NonRecoverableError( "configure nic '{0}' " "failed with this error : {1}".format(name, cr.message)) ctx.instance.runtime_properties['resource_group'] = resource_group_name ctx.instance.runtime_properties['resource'] = result ctx.instance.runtime_properties['resource_id'] = result.get("id", "") ctx.instance.runtime_properties['name'] = name