def delete_backend_pool(**_):
    '''Deletes a Load Balancer Backend Pool'''
    if ctx.node.properties.get('use_external_resource', False):
        return
    # 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)
    lb_iface = LoadBalancer(
        _ctx=lb_rel.target,
        api_version=ctx.node.properties.get('api_version',
                                            constants.API_VER_NETWORK))
    # Get the existing pools
    lb_data = lb_iface.get(lb_name)
    lb_pools = lb_data.get('properties', dict()).get(
        'backendAddressPools', list())
    for idx, pool in enumerate(lb_pools):
        if pool.get('name') == utils.get_resource_name():
            del lb_pools[idx]
    # Update the Load Balancer with the new pool list
    utils.task_resource_update(
        lb_iface,
        {
            'properties': {
                'backendAddressPools': lb_pools
            }
        },
        name=lb_name)
def create_probe(**_):
    '''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 NonRecoverableError(
            '"use_external_resource" specified without a resource "name"')
    # Generate a name if it doesn't exist
    utils.generate_resource_name(
        Probe(api_version=ctx.node.properties.get('api_version',
                                                  constants.API_VER_NETWORK)))
    # 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)
    lb_iface = LoadBalancer(api_version=ctx.node.properties.get(
        'api_version', constants.API_VER_NETWORK))
    # Get the existing probes
    lb_data = lb_iface.get(lb_name)
    lb_probes = lb_data.get('properties', dict()).get('probes', list())
    lb_probes.append({
        'name': utils.get_resource_name(),
        'properties': utils.get_resource_config()
    })
    # Update the Load Balancer with the new probe
    utils.task_resource_update(lb_iface, {'properties': {
        'probes': lb_probes
    }},
                               name=lb_name)
示例#3
0
def delete_incoming_nat_rule(**_):
    '''Deletes a Load Balancer Incoming NAT Rule'''
    if ctx.node.properties.get('use_external_resource', False):
        return
    # 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)
    lb_iface = LoadBalancer(_ctx=lb_rel.target)
    # Get the existing probes
    lb_data = lb_iface.get(lb_name)
    lb_rules = lb_data.get('properties', dict()).get(
        'inboundNatRules', list())
    for idx, rule in enumerate(lb_rules):
        if rule.get('name') == utils.get_resource_name():
            del lb_rules[idx]
    # Update the Load Balancer with the new NAT rule list
    utils.task_resource_update(
        lb_iface,
        {
            'properties': {
                'inboundNatRules': lb_rules
            }
        },
        name=lb_name)
def delete_probe(**_):
    '''Deletes a Load Balancer Probe'''
    if ctx.node.properties.get('use_external_resource', False):
        return
    # 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)
    lb_iface = LoadBalancer(_ctx=lb_rel.target)
    # Get the existing probes
    lb_data = lb_iface.get(lb_name)
    lb_probes = lb_data.get('properties', dict()).get(
        'probes', list())
    for idx, probe in enumerate(lb_probes):
        if probe.get('name') == utils.get_resource_name():
            del lb_probes[idx]
    # Update the Load Balancer with the new probes list
    utils.task_resource_update(
        lb_iface,
        {
            'properties': {
                'probes': lb_probes
            }
        },
        name=lb_name)
def delete_rule(**_):
    '''
        Deletes a Load Balancer Rule
        TODO: Rewrite this to occur inside of a Relationship Operation
    '''
    if ctx.node.properties.get('use_external_resource', False):
        return
    # 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)
    lb_ctx = utils.get_relationship_subject_ctx(ctx, lb_rel.target)
    lb_iface = LoadBalancer(_ctx=lb_ctx,
                            api_version=ctx.node.properties.get(
                                'api_version', constants.API_VER_NETWORK))
    # Get the existing rules
    lb_data = lb_iface.get(lb_name)
    lb_rules = lb_data.get('properties', dict()).get('loadBalancingRules',
                                                     list())
    for idx, rule in enumerate(lb_rules):
        if rule.get('name') == utils.get_resource_name():
            del lb_rules[idx]
    # Update the Load Balancer with the new rules list
    utils.task_resource_update(
        lb_iface, {'properties': {
            'loadBalancingRules': lb_rules
        }},
        name=lb_name)
示例#6
0
def create_backend_pool(**_):
    '''Uses an existing, or creates a new, Load Balancer Backend Pool'''
    # Check if invalid external resource
    if ctx.node.properties.get('use_external_resource', False) and \
       not ctx.node.properties.get('name'):
        raise NonRecoverableError(
            '"use_external_resource" specified without a resource "name"')
    # Generate a name if it doesn't exist
    utils.generate_resource_name(BackendAddressPool())
    # 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)
    lb_iface = LoadBalancer()
    # Get the existing pools
    lb_data = lb_iface.get(lb_name)
    lb_pools = lb_data.get('properties', dict()).get(
        'backendAddressPools', list())
    lb_pools.append({'name': utils.get_resource_name()})
    # Update the Load Balancer with the new pool
    utils.task_resource_update(
        lb_iface,
        {
            'properties': {
                'backendAddressPools': lb_pools
            }
        },
        name=lb_name)
示例#7
0
def delete_backend_pool(**_):
    '''Deletes a Load Balancer Backend Pool'''
    if ctx.node.properties.get('use_external_resource', False):
        return
    # 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)
    lb_iface = LoadBalancer(_ctx=lb_rel.target)
    # Get the existing pools
    lb_data = lb_iface.get(lb_name)
    lb_pools = lb_data.get('properties', dict()).get(
        'backendAddressPools', list())
    for idx, pool in enumerate(lb_pools):
        if pool.get('name') == utils.get_resource_name():
            del lb_pools[idx]
    # Update the Load Balancer with the new pool list
    utils.task_resource_update(
        lb_iface,
        {
            'properties': {
                'backendAddressPools': lb_pools
            }
        },
        name=lb_name)
def create_probe(**_):
    '''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 NonRecoverableError(
            '"use_external_resource" specified without a resource "name"')
    # Generate a name if it doesn't exist
    utils.generate_resource_name(Probe(api_version=ctx.node.properties.get(
            'api_version', constants.API_VER_NETWORK)))
    # 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)
    lb_iface = LoadBalancer(api_version=ctx.node.properties.get(
            'api_version', constants.API_VER_NETWORK))
    # Get the existing probes
    lb_data = lb_iface.get(lb_name)
    lb_probes = lb_data.get('properties', dict()).get(
        'probes', list())
    lb_probes.append({
        'name': utils.get_resource_name(),
        'properties': utils.get_resource_config()
    })
    # Update the Load Balancer with the new probe
    utils.task_resource_update(
        lb_iface,
        {
            'properties': {
                'probes': lb_probes
            }
        },
        name=lb_name)
def delete_incoming_nat_rule(**_):
    '''Deletes a Load Balancer Incoming NAT Rule'''
    if ctx.node.properties.get('use_external_resource', False):
        return
    # 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)
    lb_iface = LoadBalancer(
        _ctx=lb_rel.target,
        api_version=ctx.node.properties.get('api_version',
                                            constants.API_VER_NETWORK))
    # Get the existing probes
    lb_data = lb_iface.get(lb_name)
    lb_rules = lb_data.get('properties', dict()).get(
        'inboundNatRules', list())
    for idx, rule in enumerate(lb_rules):
        if rule.get('name') == utils.get_resource_name():
            del lb_rules[idx]
    # Update the Load Balancer with the new NAT rule list
    utils.task_resource_update(
        lb_iface,
        {
            'properties': {
                'inboundNatRules': lb_rules
            }
        },
        name=lb_name)
def delete_rule(**_):
    '''
        Deletes a Load Balancer Rule
        TODO: Rewrite this to occur inside of a Relationship Operation
    '''
    if ctx.node.properties.get('use_external_resource', False):
        return
    # 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)
    lb_ctx = utils.get_relationship_subject_ctx(ctx, lb_rel.target)
    lb_iface = LoadBalancer(_ctx=lb_ctx, api_version=ctx.node.properties.get(
            'api_version', constants.API_VER_NETWORK))
    # Get the existing rules
    lb_data = lb_iface.get(lb_name)
    lb_rules = lb_data.get('properties', dict()).get(
        'loadBalancingRules', list())
    for idx, rule in enumerate(lb_rules):
        if rule.get('name') == utils.get_resource_name():
            del lb_rules[idx]
    # Update the Load Balancer with the new rules list
    utils.task_resource_update(
        lb_iface,
        {
            'properties': {
                'loadBalancingRules': lb_rules
            }
        },
        name=lb_name)
示例#11
0
def configure(command_to_execute, file_uris, type_handler_version='v2.0', **_):
    '''Configures the resource'''
    os_family = ctx.node.properties.get('os_family', '').lower()
    if os_family == 'windows':
        utils.task_resource_create(
            VirtualMachineExtension(virtual_machine=utils.get_resource_name()),
            {
                'location': ctx.node.properties.get('location'),
                'tags': ctx.node.properties.get('tags'),
                'properties': {
                    'publisher': 'Microsoft.Compute',
                    'type': 'CustomScriptExtension',
                    'typeHandlerVersion': type_handler_version,
                    'settings': {
                        'fileUris': file_uris,
                        'commandToExecute': command_to_execute
                    }
                }
            })

    # Write the IP address to runtime properties for the agent
    # Get a reference to the NIC
    rel_nic = utils.get_relationship_by_type(ctx.instance.relationships,
                                             constants.REL_CONNECTED_TO_NIC)
    # No NIC? Exit and hope the user doesn't plan to install an agent
    if not rel_nic:
        return
    # Get the NIC data from the API directly (because of IPConfiguration)
    nic = NetworkInterfaceCard(_ctx=rel_nic.target)
    nic_data = nic.get(utils.get_resource_name(rel_nic.target))
    # Iterate over each IPConfiguration entry
    for ip_cfg in nic_data.get('properties',
                               dict()).get('ipConfigurations', list()):
        # Get the Private IP Address endpoint
        ctx.instance.runtime_properties['ip'] = \
            ip_cfg.get('properties', dict()).get('privateIPAddress')
        # Get the Public IP Address endpoint
        pubip_id = ip_cfg.get('properties',
                              dict()).get('publicIPAddress', dict()).get('id')
        if isinstance(pubip_id, basestring):
            # use the ID to get the data on the public ip
            pubip = PublicIPAddress(_ctx=rel_nic.target)
            pubip.endpoint = '{0}{1}'.format(constants.CONN_API_ENDPOINT,
                                             pubip_id)
            pubip_data = pubip.get()
            if isinstance(pubip_data, dict):
                ctx.instance.runtime_properties['public_ip'] = \
                    pubip_data.get('properties', dict()).get('ipAddress')
    # See if the user wants to use the public IP as primary IP
    if ctx.node.properties.get('use_public_ip') and \
            ctx.instance.runtime_properties.get('public_ip'):
        ctx.instance.runtime_properties['ip'] = \
            ctx.instance.runtime_properties.get('public_ip')
    ctx.logger.info('OUTPUT {0}.{1} = "{2}"'.format(
        ctx.instance.id, 'ip', ctx.instance.runtime_properties.get('ip')))
    ctx.logger.info('OUTPUT {0}.{1} = "{2}"'.format(
        ctx.instance.id, 'public_ip',
        ctx.instance.runtime_properties.get('public_ip')))
def create_rule(**_):
    '''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 NonRecoverableError(
            '"use_external_resource" specified without a resource "name"')
    # Generate a name if it doesn't exist
    utils.generate_resource_name(LoadBalancerRule(
        api_version=ctx.node.properties.get('api_version',
                                            constants.API_VER_NETWORK)))
    # Get the resource config
    res_cfg = utils.get_resource_config()
    # 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)
    lb_iface = LoadBalancer(api_version=ctx.node.properties.get(
            'api_version', constants.API_VER_NETWORK))
    lb_data = lb_iface.get(lb_name)
    # Get the Load Balancer Backend Pool
    lb_be_pool_id = utils.get_rel_id_reference(
        BackendAddressPool, constants.REL_CONNECTED_TO_LB_BE_POOL)
    # Get the Load Balancer Probe
    lb_probe_id = utils.get_rel_id_reference(
        Probe, constants.REL_CONNECTED_TO_LB_PROBE)
    # Get the Load Balancer Frontend IP Configuration
    lb_fe_ipc_name = utils.get_rel_node_name(constants.REL_CONNECTED_TO_IPC)
    lb_fe_ipc_id = utils.get_full_resource_id(
        FrontendIPConfiguration(api_version=ctx.node.properties.get(
            'api_version', constants.API_VER_NETWORK)
        ), lb_fe_ipc_name)
    # Get the existing Load Balancer Rules
    lb_rules = lb_data.get('properties', dict()).get(
        'loadBalancingRules', list())
    # Update the resource config
    res_cfg['backendAddressPool'] = lb_be_pool_id
    res_cfg['frontendIPConfiguration'] = lb_fe_ipc_id
    res_cfg['probe'] = lb_probe_id
    lb_rules.append({
        'name': utils.get_resource_name(),
        'properties': res_cfg
    })
    # Update the Load Balancer with the new rule
    utils.task_resource_update(
        lb_iface,
        {
            'properties': {
                'loadBalancingRules': lb_rules
            }
        },
        name=lb_name)
示例#13
0
def create_rule(**_):
    '''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 NonRecoverableError(
            '"use_external_resource" specified without a resource "name"')
    # Generate a name if it doesn't exist
    utils.generate_resource_name(LoadBalancerRule())
    # Get the resource config
    res_cfg = utils.get_resource_config()
    # 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)
    lb_iface = LoadBalancer()
    lb_data = lb_iface.get(lb_name)
    # Get the Load Balancer Backend Pool
    lb_be_pool_id = utils.get_rel_id_reference(
        BackendAddressPool, constants.REL_CONNECTED_TO_LB_BE_POOL)
    # Get the Load Balancer Probe
    lb_probe_id = utils.get_rel_id_reference(
        Probe, constants.REL_CONNECTED_TO_LB_PROBE)
    # Get the Load Balancer Frontend IP Configuration
    lb_fe_ipc_name = utils.get_rel_node_name(constants.REL_CONNECTED_TO_IPC)
    lb_fe_ipc_id = utils.get_full_resource_id(
        FrontendIPConfiguration(), lb_fe_ipc_name)
    # Get the existing Load Balancer Rules
    lb_rules = lb_data.get('properties', dict()).get(
        'loadBalancingRules', list())
    # Update the resource config
    res_cfg['backendAddressPool'] = lb_be_pool_id
    res_cfg['frontendIPConfiguration'] = lb_fe_ipc_id
    res_cfg['probe'] = lb_probe_id
    lb_rules.append({
        'name': utils.get_resource_name(),
        'properties': res_cfg
    })
    # Update the Load Balancer with the new rule
    utils.task_resource_update(
        lb_iface,
        {
            'properties': {
                'loadBalancingRules': lb_rules
            }
        },
        name=lb_name)
    def list_keys(self, name=None):
        '''
            Calls /listKeys

        :param string name: Name of the existing resource
        :returns: Response data from the Azure API call
        :rtype: dict
        :raises: :exc:`cloudify.exceptions.RecoverableError`
        '''
        # Get the resource name
        name = name or utils.get_resource_name(self.ctx)
        url = '{0}/{1}/listKeys'.format(self.endpoint, name)
        res = self.client.request(
            method='post',
            url=url)
        if res.status_code != httplib.OK:
            raise RecoverableError(
                'Unexpected status returned after calling '
                '/listKeys. Status={0}'.format(res.status_code))
        keys = res.json()
        ret = list()
        for key in keys:
            ret.append({
                'name': key,
                'key': keys[key]
            })
        return ret
def attach_ip_configuration(**_):
    '''Generates a usable UUID for the NIC's IP Configuration'''
    # Generate the IPConfiguration's name
    utils.generate_resource_name(FrontendIPConfiguration(
        load_balancer_name=utils.get_resource_name(_ctx=ctx.source),
        _ctx=ctx.target),
                                 _ctx=ctx.target)
def get_resource_group_name_deployment_name_and_api_version(ctx):
    deployment_name = utils.get_resource_name(ctx)
    resource_group_name = ctx.node.properties.get('resource_group_name',
                                                  deployment_name)
    api_version = \
        ctx.node.properties.get('api_version', constants.API_VER_RESOURCES)
    return deployment_name, resource_group_name, api_version
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 build_osdisk_profile(usr_osdisk=None):
    '''
        Creates a storageProfile::osDisk object for use when
        creating a Virtual Machine

    :param dict usr_osdisk: User-override data
    :returns: storageProfile::osDisk object
    :rtype: dict
    '''
    osdisk = dict()
    if isinstance(usr_osdisk, dict):
        osdisk = deepcopy(usr_osdisk)
    # Generate disk name if one wasn't provided
    osdisk['name'] = osdisk.get('name') or utils.get_resource_name()
    # If no disk URI was specified, generate one
    if not osdisk.get('vhd', dict()).get('uri'):
        osdisk['vhd'] = {
            'uri': 'http://{0}.{1}/vhds/{2}.vhd'.format(
                utils.get_rel_node_name(constants.REL_CONNECTED_TO_SA),
                'blob.core.windows.net',
                osdisk.get('name'))
        }
    # Fill in the blanks if the user didn't specify
    osdisk['caching'] = osdisk.get('caching', 'ReadWrite')
    osdisk['createOption'] = osdisk.get('createOption', 'FromImage')
    return osdisk
def attach_ip_configuration(**_):
    '''Generates a usable UUID for the NIC's IP Configuration'''
    # Generate the IPConfiguration's name
    utils.generate_resource_name(IPConfiguration(
        network_interface_card=utils.get_resource_name(_ctx=ctx.source),
        _ctx=ctx.target
    ), _ctx=ctx.target)
def detach_nic_from_backend_pool(**_):
    '''
        Detaches a Network Interface Card's IPConfigurations
        from a Load Balancer Backend Pool
    '''
    # Get the ID of the Backend Pool
    be_pool_id = utils.get_full_id_reference(
        BackendAddressPool, _ctx=ctx.target)
    # Get an interface to the Network Interface Card
    nic_iface = NetworkInterfaceCard(_ctx=ctx.source)
    # Get the existing NIC IPConfigurations
    nic_data = nic_iface.get(utils.get_resource_name(ctx.source))
    nic_ip_cfgs = nic_data.get('properties', dict()).get(
        'ipConfigurations', list())
    # Remove the Backend Pool from the NIC IPConfigurations
    for ip_idx, _ in enumerate(nic_ip_cfgs):
        nic_pools = nic_ip_cfgs[ip_idx].get(
            'properties', dict()).get(
                LB_ADDRPOOLS_KEY, list())
        for pool_idx, nic_pool in enumerate(nic_pools):
            if nic_pool != be_pool_id:
                continue
            del nic_pools[pool_idx]
            nic_ip_cfgs[ip_idx]['properties'][LB_ADDRPOOLS_KEY] = nic_pools
    # Update the NIC IPConfigurations
    utils.task_resource_update(
        nic_iface,
        {
            'properties': {
                'ipConfigurations': nic_ip_cfgs
            }
        }, _ctx=ctx.source)
示例#21
0
def build_ip_configuration(ipc):
    '''
        Attempts to construct a proper IP Configuration from
        a context object

    :params `cloudify.context.RelationshipSubjectContext` ipc:
        IP Configuration context object
    :returns: IP Configuration dict
    :rtype: dict or None
    '''
    if not ipc or not ipc.instance.relationships:
        return None
    # Find a referenced Subnet
    subnet = utils.get_rel_id_reference(Subnet,
                                        constants.REL_IPC_CONNECTED_TO_SUBNET,
                                        _ctx=ipc)
    # Find a referenced Public IP
    pubip = utils.get_rel_id_reference(PublicIPAddress,
                                       constants.REL_IPC_CONNECTED_TO_PUBIP,
                                       _ctx=ipc)

    # Build a partial config and update it with properties config
    return utils.dict_update(
        {
            'name': utils.get_resource_name(ipc),
            'properties': {
                'subnet': subnet,
                'publicIPAddress': pubip
            }
        }, utils.get_resource_config(_ctx=ipc))
def build_datadisks_profile(usr_datadisks):
    '''
        Creates a list of storageProfile::dataDisk objects for use when
        creating a Virtual Machine

    :param dict usr_datadisks: User data
    :returns: List of storageProfile::dataDisk objects
    :rtype: list
    '''
    datadisks = list()
    if not usr_datadisks:
        return list()
    for idx, usr_datadisk in enumerate(usr_datadisks):
        datadisk = deepcopy(usr_datadisk)
        # Generate disk name if one wasn't provided
        datadisk['name'] = datadisk.get('name') or \
            '{0}-{1}'.format(utils.get_resource_name(), idx)
        # If no disk URI was specified, generate one
        if not datadisk.get('vhd', dict()).get('uri'):
            datadisk['vhd'] = {
                'uri':
                'http://{0}.{1}/vhds/{2}.vhd'.format(
                    utils.get_rel_node_name(constants.REL_CONNECTED_TO_SA),
                    'blob.' + ctx.node.properties['storage_endpoint'],
                    datadisk.get('name'))
            }
        # Fill in the blanks if the user didn't specify
        datadisk['lun'] = datadisk.get('lun', idx)
        datadisk['createOption'] = datadisk.get('createOption', 'Empty')
        datadisks.append(datadisk)
    return datadisks
def detach_nic_from_backend_pool(**_):
    '''
        Detaches a Network Interface Card's IPConfigurations
        from a Load Balancer Backend Pool
    '''
    # Get the ID of the Backend Pool
    be_pool_id = utils.get_full_id_reference(BackendAddressPool,
                                             _ctx=ctx.target)
    # Get an interface to the Network Interface Card
    nic_iface = NetworkInterfaceCard(_ctx=ctx.source)
    # Get the existing NIC IPConfigurations
    nic_data = nic_iface.get(utils.get_resource_name(ctx.source))
    nic_ip_cfgs = nic_data.get('properties',
                               dict()).get('ipConfigurations', list())
    # Remove the Backend Pool from the NIC IPConfigurations
    for ip_idx, _ in enumerate(nic_ip_cfgs):
        nic_pools = nic_ip_cfgs[ip_idx].get('properties', dict()).get(
            LB_ADDRPOOLS_KEY, list())
        for pool_idx, nic_pool in enumerate(nic_pools):
            if nic_pool != be_pool_id:
                continue
            del nic_pools[pool_idx]
            nic_ip_cfgs[ip_idx]['properties'][LB_ADDRPOOLS_KEY] = nic_pools
    # Update the NIC IPConfigurations
    utils.task_resource_update(
        nic_iface, {'properties': {
            'ipConfigurations': nic_ip_cfgs
        }},
        _ctx=ctx.source)
def attach_ip_configuration(**_):
    '''Generates a usable UUID for the NIC's IP Configuration'''
    # Generate the IPConfiguration's name
    utils.generate_resource_name(FrontendIPConfiguration(
        load_balancer_name=utils.get_resource_name(_ctx=ctx.source),
        _ctx=ctx.target
    ), _ctx=ctx.target)
def build_ip_configuration(ipc):
    '''
        Attempts to construct a proper IP Configuration from
        a context object

    :params `cloudify.context.RelationshipSubjectContext` ipc:
        IP Configuration context object
    :returns: IP Configuration dict
    :rtype: dict or None
    '''
    if not ipc or not ipc.instance.relationships:
        return None
    # Find a referenced Subnet
    subnet = utils.get_rel_id_reference(
        Subnet,
        constants.REL_IPC_CONNECTED_TO_SUBNET,
        _ctx=ipc)
    # Find a referenced Public IP
    pubip = utils.get_rel_id_reference(
        PublicIPAddress,
        constants.REL_IPC_CONNECTED_TO_PUBIP,
        _ctx=ipc)
    ip_configuration = {
        'name': utils.get_resource_name(ipc),
        'properties': {
            'subnet': subnet,
            'publicIPAddress': pubip
        }
    }
    ip_configuration['properties'] = utils.dict_update(
        ip_configuration['properties'],
        utils.get_resource_config(_ctx=ipc))
    return ip_configuration
def build_osdisk_profile(usr_osdisk=None):
    '''
        Creates a storageProfile::osDisk object for use when
        creating a Virtual Machine

    :param dict usr_osdisk: User-override data
    :returns: storageProfile::osDisk object
    :rtype: dict
    '''
    osdisk = dict()
    if isinstance(usr_osdisk, dict):
        osdisk = deepcopy(usr_osdisk)
    # Generate disk name if one wasn't provided
    osdisk['name'] = osdisk.get('name') or utils.get_resource_name()
    # If no disk URI was specified, generate one
    # Unless this is a managedDisk.
    if not osdisk.get('vhd', dict()).get('uri') and \
            'managedDisk' not in osdisk:
        osdisk['vhd'] = {
            'uri':
            'http://{0}.{1}/vhds/{2}.vhd'.format(
                utils.get_rel_node_name(constants.REL_CONNECTED_TO_SA),
                'blob.' + ctx.node.properties['storage_endpoint'],
                osdisk.get('name'))
        }
    # Fill in the blanks if the user didn't specify
    osdisk['caching'] = osdisk.get('caching', 'ReadWrite')
    osdisk['createOption'] = osdisk.get('createOption', 'FromImage')
    return osdisk
def detach_data_disk(**_):
    '''Detaches a data disk'''
    vm_iface = VirtualMachine(_ctx=ctx.source,
                              api_version=ctx.source.node.properties.get(
                                  'api_version', constants.API_VER_COMPUTE))
    vm_state = vm_iface.get(name=utils.get_resource_name(_ctx=ctx.source))
    data_disks = [
        x for x in vm_state.get('properties', dict()).get(
            'storageProfile', dict()).get('dataDisks', list())
        if x.get('vhd', dict()).get('uri') !=
        ctx.target.instance.runtime_properties['uri']
    ]
    ctx.logger.info('async_op: {0}'.format(
        ctx.source.instance.runtime_properties.get('async_op')))
    # Update the VM
    utils.task_resource_update(
        VirtualMachine(_ctx=ctx.source,
                       api_version=ctx.source.node.properties.get(
                           'api_version', constants.API_VER_COMPUTE)),
        {
            'location': ctx.source.node.properties.get('location'),
            'properties': {
                'storageProfile': {
                    'dataDisks': data_disks
                }
            }
        },
        force=True,
        _ctx=ctx.source)
    def list_keys(self, name=None):
        '''
            Calls /listKeys

        :param string name: Name of the existing resource
        :returns: Response data from the Azure API call
        :rtype: dict
        :raises: :exc:`cloudify.exceptions.RecoverableError`
        '''
        # Get the resource name
        name = name or utils.get_resource_name(self.ctx)
        url = '{0}/{1}/listKeys'.format(self.endpoint, name)
        res = self.client.request(
            method='post',
            url=url)
        if res.status_code != httplib.OK:
            raise RecoverableError(
                'Unexpected status returned after calling '
                '/listKeys. Status={0}'.format(res.status_code))
        keys = res.json()
        ret = list()
        for key in keys:
            ret.append({
                'name': key,
                'key': keys[key]
            })
        return ret
def build_datadisks_profile(usr_datadisks):
    '''
        Creates a list of storageProfile::dataDisk objects for use when
        creating a Virtual Machine

    :param dict usr_datadisks: User data
    :returns: List of storageProfile::dataDisk objects
    :rtype: list
    '''
    datadisks = list()
    if not usr_datadisks:
        return list()
    for idx, usr_datadisk in enumerate(usr_datadisks):
        datadisk = deepcopy(usr_datadisk)
        # Generate disk name if one wasn't provided
        datadisk['name'] = datadisk.get('name') or \
            '{0}-{1}'.format(utils.get_resource_name(), idx)
        # If no disk URI was specified, generate one
        if not datadisk.get('vhd', dict()).get('uri'):
            datadisk['vhd'] = {
                'uri': 'http://{0}.{1}/vhds/{2}.vhd'.format(
                    utils.get_rel_node_name(constants.REL_CONNECTED_TO_SA),
                    'blob.core.windows.net',
                    datadisk.get('name'))
            }
        # Fill in the blanks if the user didn't specify
        datadisk['lun'] = datadisk.get('lun', idx)
        datadisk['createOption'] = datadisk.get('createOption', 'Empty')
        datadisks.append(datadisk)
    return datadisks
def detach_data_disk(**_):
    '''Detaches a data disk'''
    vm_iface = VirtualMachine(_ctx=ctx.source)
    vm_state = vm_iface.get(name=utils.get_resource_name(_ctx=ctx.source))
    data_disks = [
        x for x in vm_state.get(
            'properties', dict()).get(
                'storageProfile', dict()).get(
                    'dataDisks', list())
        if x.get('vhd', dict()).get('uri') !=
        ctx.target.instance.runtime_properties['uri']
    ]
    ctx.logger.info('async_op: {0}'.format(
        ctx.source.instance.runtime_properties.get('async_op')))
    # Update the VM
    utils.task_resource_update(
        VirtualMachine(_ctx=ctx.source),
        {
            'location': ctx.source.node.properties.get('location'),
            'properties': {
                'storageProfile': {
                    'dataDisks': data_disks
                }
            }
        },
        force=True,
        _ctx=ctx.source
    )
def delete(ctx, **_):
    """Deletes a Resource Group"""
    if ctx.node.properties.get('use_external_resource', False):
        return
    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)
    api_version = \
        ctx.node.properties.get('api_version', constants.API_VER_RESOURCES)
    resource_group = ResourceGroup(azure_config, ctx.logger, api_version)
    try:
        resource_group.get(name)
    except CloudError:
        ctx.logger.info("Resource with name {0} doesn't exist".format(name))
        return
    try:
        resource_group.delete(name)
        utils.runtime_properties_cleanup(ctx)
    except CloudError as cr:
        raise cfy_exc.NonRecoverableError(
            "delete resource_group '{0}' "
            "failed with this error : {1}".format(name, cr.message))
def create(ctx, **_):
    """Uses an existing, or creates a new, Resource Group"""
    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_params = {
        'location': ctx.node.properties.get('location'),
        'tags': ctx.node.properties.get('tags')
    }
    api_version = \
        ctx.node.properties.get('api_version', constants.API_VER_RESOURCES)
    resource_group = ResourceGroup(azure_config, ctx.logger, api_version)
    try:
        result = \
            resource_group.create_or_update(
                name,
                resource_group_params)
    except CloudError as cr:
        raise cfy_exc.NonRecoverableError(
            "create resource_group '{0}' "
            "failed with this error : {1}".format(name, cr.message))

    ctx.instance.runtime_properties['resource'] = result
    ctx.instance.runtime_properties['resource_id'] = result.get("id", "")
示例#33
0
def attach_ip_configuration(**_):
    '''Generates a usable UUID for the NIC's IP Configuration'''
    # Generate the IPConfiguration's name
    utils.generate_resource_name(IPConfiguration(
        network_interface_card=utils.get_resource_name(_ctx=ctx.source),
        _ctx=ctx.target),
                                 _ctx=ctx.target)
def create(ctx, **_):
    """Uses an existing, or creates a new, Load Balancer"""
    name = utils.get_resource_name(ctx)
    resource_group_name = utils.get_resource_group(ctx)
    ctx.logger.info("Created Load Balancer with name {0} "
                    "inside ResourceGroup {1}".format(name,
                                                      resource_group_name))
    ctx.instance.runtime_properties['resource_group'] = resource_group_name
def attach_data_disk(lun, **_):
    '''Attaches a data disk'''
    vm_iface = VirtualMachine(_ctx=ctx.source,
                              api_version=ctx.source.node.properties.get(
                                  'api_version', constants.API_VER_COMPUTE))
    vm_state = vm_iface.get(name=utils.get_resource_name(_ctx=ctx.source))
    data_disks = vm_state.get('properties',
                              dict()).get('storageProfile',
                                          dict()).get('dataDisks', list())
    # Get the createOption
    create_opt = 'Empty'
    if ctx.target.node.properties.get('use_external_resource', False):
        create_opt = 'Attach'
    # Add the disk to the list
    data_disks.append({
        'name':
        utils.get_resource_name(_ctx=ctx.target),
        'lun':
        lun,
        'diskSizeGB':
        ctx.target.instance.runtime_properties['diskSizeGB'],
        'vhd': {
            'uri': ctx.target.instance.runtime_properties['uri']
        },
        'createOption':
        create_opt,
        'caching':
        'None'
    })
    ctx.logger.info('async_op: {0}'.format(
        ctx.source.instance.runtime_properties.get('async_op')))
    # Update the VM
    utils.task_resource_update(
        VirtualMachine(_ctx=ctx.source,
                       api_version=ctx.source.node.properties.get(
                           'api_version', constants.API_VER_COMPUTE)),
        {
            'location': ctx.source.node.properties.get('location'),
            'properties': {
                'storageProfile': {
                    'dataDisks': data_disks
                }
            }
        },
        force=True,
        _ctx=ctx.source)
def configure(**_):
    '''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 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('properties', dict()).get('publicIPAddress'):
            if ip_cfg.get('properties', dict()).get('subnet'):
                del ip_cfg['properties']['subnet']
    # Create a resource (if necessary)
    utils.task_resource_create(
        LoadBalancer(api_version=ctx.node.properties.get(
            'api_version', constants.API_VER_NETWORK)), {
                'location':
                ctx.node.properties.get('location'),
                'tags':
                ctx.node.properties.get('tags'),
                'properties':
                utils.dict_update(utils.get_resource_config(),
                                  {'frontendIPConfigurations': fe_ip_cfg})
            })
    # Get an interface to the Load Balancer
    lb_iface = LoadBalancer(api_version=ctx.node.properties.get(
        'api_version', constants.API_VER_NETWORK))
    lb_data = lb_iface.get(utils.get_resource_name())
    # Get the ID of the Frontend IP Configuration
    for fe_ipc_data in lb_data.get('properties',
                                   dict()).get('frontendIPConfigurations',
                                               list()):
        ipc_iface = IPConfiguration()
        ipc_id = fe_ipc_data.get('id')
        if not ipc_id:
            break
        ipc_iface.endpoint = '{0}{1}'.format(constants.CONN_API_ENDPOINT,
                                             ipc_id)
        # Get the Frontend private IP address
        ipc_data = ipc_iface.get()
        ctx.instance.runtime_properties['ip'] = \
            ipc_data.get('properties', dict()).get('privateIPAddress')
        # Get the ID of the Frontend Public IP Configuration
        pipc_iface = PublicIPAddress()
        pipc_id = fe_ipc_data.get('properties',
                                  dict()).get('publicIPAddress',
                                              dict()).get('id')
        if not pipc_id:
            break
        pipc_iface.endpoint = '{0}{1}'.format(constants.CONN_API_ENDPOINT,
                                              pipc_id)
        # Get the Frontend public IP address
        pipc_data = pipc_iface.get()
        ctx.instance.runtime_properties['public_ip'] = \
            pipc_data.get('properties', dict()).get('ipAddress')
def start(**_):
    '''
        Stores NIC IPs in runtime properties.
    '''

    creds = utils.get_credentials(_ctx=ctx)

    nic_iface = NetworkInterfaceCard(
        _ctx=ctx,
        api_version=ctx.node.properties.get(
            'api_version',
            constants.API_VER_NETWORK))
    nic_name = utils.get_resource_name(ctx)
    nic_data = nic_iface.get(nic_name)

    for ip_cfg in nic_data.get(
            'properties', dict()).get(
                'ipConfigurations', list()):

        # Get the Private IP Address endpoint
        ctx.instance.runtime_properties['ip'] = \
            ip_cfg.get('properties', dict()).get('privateIPAddress')

        # Get the Public IP Address endpoint
        pubip_id = ip_cfg.get(
            'properties', dict()).get(
            'publicIPAddress', dict()).get('id')
        if isinstance(pubip_id, basestring):
            # use the ID to get the data on the public ip
            pubip = PublicIPAddress(
                _ctx=ctx,
                api_version=ctx.node.properties.get(
                    'api_version',
                    constants.API_VER_NETWORK))
            pubip.endpoint = '{0}{1}'.format(
                creds.endpoints_resource_manager, pubip_id)
            pubip_data = pubip.get()
            if isinstance(pubip_data, dict):
                public_ip = \
                    pubip_data.get('properties', dict()).get('ipAddress')
                # Maintained for backwards compatibility.
                ctx.instance.runtime_properties['public_ip'] = \
                    public_ip
                # For consistency with other plugins.
                ctx.instance.runtime_properties[PUBLIC_IP_PROPERTY] = \
                    public_ip

            # We should also consider that maybe there will be many
            # public ip addresses.
            public_ip_addresses = \
                ctx.instance.runtime_properties.get(
                    PUBLIC_IP_PROPERTY, [])
            if public_ip not in public_ip_addresses:
                public_ip_addresses.append(public_ip)
            ctx.instance.runtime_properties['public_ip_addresses'] = \
                public_ip_addresses
def configure(**_):
    '''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 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('properties', dict()).get('publicIPAddress'):
            if ip_cfg.get('properties', dict()).get('subnet'):
                del ip_cfg['properties']['subnet']
    # Create a resource (if necessary)
    utils.task_resource_create(
        LoadBalancer(api_version=ctx.node.properties.get(
            'api_version', constants.API_VER_NETWORK)),
        {
            'location': ctx.node.properties.get('location'),
            'tags': ctx.node.properties.get('tags'),
            'properties': utils.dict_update(
                utils.get_resource_config(),
                {
                    'frontendIPConfigurations': fe_ip_cfg
                })
        })
    # Get an interface to the Load Balancer
    lb_iface = LoadBalancer(api_version=ctx.node.properties.get(
            'api_version', constants.API_VER_NETWORK))
    lb_data = lb_iface.get(utils.get_resource_name())
    # Get the ID of the Frontend IP Configuration
    for fe_ipc_data in lb_data.get('properties', dict()).get(
            'frontendIPConfigurations', list()):
        ipc_iface = IPConfiguration()
        ipc_id = fe_ipc_data.get('id')
        if not ipc_id:
            break
        ipc_iface.endpoint = '{0}{1}'.format(
            constants.CONN_API_ENDPOINT, ipc_id)
        # Get the Frontend private IP address
        ipc_data = ipc_iface.get()
        ctx.instance.runtime_properties['ip'] = \
            ipc_data.get('properties', dict()).get('privateIPAddress')
        # Get the ID of the Frontend Public IP Configuration
        pipc_iface = PublicIPAddress()
        pipc_id = fe_ipc_data.get('properties', dict()).get(
            'publicIPAddress', dict()).get('id')
        if not pipc_id:
            break
        pipc_iface.endpoint = '{0}{1}'.format(
            constants.CONN_API_ENDPOINT, pipc_id)
        # Get the Frontend public IP address
        pipc_data = pipc_iface.get()
        ctx.instance.runtime_properties['public_ip'] = \
            pipc_data.get('properties', dict()).get('ipAddress')
def attach_data_disk(lun, **_):
    '''Attaches a data disk'''
    vm_iface = VirtualMachine(_ctx=ctx.source,
                              api_version=ctx.source.node.properties.get(
                                    'api_version', constants.API_VER_COMPUTE))
    vm_state = vm_iface.get(name=utils.get_resource_name(_ctx=ctx.source))
    data_disks = vm_state.get(
        'properties', dict()).get(
            'storageProfile', dict()).get(
                'dataDisks', list())
    # Get the createOption
    create_opt = 'Empty'
    if ctx.target.node.properties.get('use_external_resource', False):
        create_opt = 'Attach'
    # Add the disk to the list
    data_disks.append({
        'name': utils.get_resource_name(_ctx=ctx.target),
        'lun': lun,
        'diskSizeGB': ctx.target.instance.runtime_properties['diskSizeGB'],
        'vhd': {
            'uri': ctx.target.instance.runtime_properties['uri']
        },
        'createOption': create_opt,
        'caching': 'None'
    })
    ctx.logger.info('async_op: {0}'.format(
        ctx.source.instance.runtime_properties.get('async_op')))
    # Update the VM
    utils.task_resource_update(
        VirtualMachine(_ctx=ctx.source,
                       api_version=ctx.source.node.properties.get(
                            'api_version', constants.API_VER_COMPUTE)),
        {
            'location': ctx.source.node.properties.get('location'),
            'properties': {
                'storageProfile': {
                    'dataDisks': data_disks
                }
            }
        },
        force=True,
        _ctx=ctx.source
    )
示例#40
0
def create_incoming_nat_rule(**_):
    '''Uses an existing, or creates a new, Load Balancer Incoming NAT Rule'''
    # Check if invalid external resource
    if ctx.node.properties.get('use_external_resource', False) and \
       not ctx.node.properties.get('name'):
        raise NonRecoverableError(
            '"use_external_resource" specified without a resource "name"')
    # Generate a name if it doesn't exist
    utils.generate_resource_name(InboundNATRule())
    # 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)
    lb_iface = LoadBalancer()
    # Get the resource config
    res_cfg = utils.get_resource_config()
    # Get the existing rules
    lb_data = lb_iface.get(lb_name)
    lb_rules = lb_data.get('properties', dict()).get(
        'inboundNatRules', list())
    # Get the Load Balancer Frontend IP Configuration
    lb_fe_ipc_name = utils.get_rel_node_name(constants.REL_CONNECTED_TO_IPC)
    lb_fe_ipc_id = utils.get_full_resource_id(
        FrontendIPConfiguration(), lb_fe_ipc_name)
    # Update the resource config
    res_cfg['frontendIPConfiguration'] = lb_fe_ipc_id
    lb_rules.append({
        'name': utils.get_resource_name(),
        'properties': res_cfg
    })
    # Update the Load Balancer with the new NAT rule
    utils.task_resource_update(
        lb_iface,
        {
            'properties': {
                'inboundNatRules': lb_rules
            }
        },
        name=lb_name)
示例#41
0
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", "")
示例#42
0
def start(**_):
    '''
        Stores NIC IPs in runtime properties.
    '''

    creds = utils.get_credentials(_ctx=ctx)

    nic_iface = NetworkInterfaceCard(_ctx=ctx,
                                     api_version=ctx.node.properties.get(
                                         'api_version',
                                         constants.API_VER_NETWORK))
    nic_name = utils.get_resource_name(ctx)
    nic_data = nic_iface.get(nic_name)

    for ip_cfg in nic_data.get('properties',
                               dict()).get('ipConfigurations', list()):

        # Get the Private IP Address endpoint
        ctx.instance.runtime_properties['ip'] = \
            ip_cfg.get('properties', dict()).get('privateIPAddress')

        # Get the Public IP Address endpoint
        pubip_id = ip_cfg.get('properties',
                              dict()).get('publicIPAddress', dict()).get('id')
        if isinstance(pubip_id, basestring):
            # use the ID to get the data on the public ip
            pubip = PublicIPAddress(_ctx=ctx,
                                    api_version=ctx.node.properties.get(
                                        'api_version',
                                        constants.API_VER_NETWORK))
            pubip.endpoint = '{0}{1}'.format(creds.endpoints_resource_manager,
                                             pubip_id)
            pubip_data = pubip.get()
            if isinstance(pubip_data, dict):
                public_ip = \
                    pubip_data.get('properties', dict()).get('ipAddress')
                # Maintained for backwards compatibility.
                ctx.instance.runtime_properties['public_ip'] = \
                    public_ip
                # For consistency with other plugins.
                ctx.instance.runtime_properties[PUBLIC_IP_PROPERTY] = \
                    public_ip

            # We should also consider that maybe there will be many
            # public ip addresses.
            public_ip_addresses = \
                ctx.instance.runtime_properties.get(
                    PUBLIC_IP_PROPERTY, [])
            if public_ip not in public_ip_addresses:
                public_ip_addresses.append(public_ip)
            ctx.instance.runtime_properties['public_ip_addresses'] = \
                public_ip_addresses
def delete_probe(**_):
    '''Deletes a Load Balancer Probe'''
    if ctx.node.properties.get('use_external_resource', False):
        return
    # 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)
    lb_iface = LoadBalancer(_ctx=lb_rel.target,
                            api_version=ctx.node.properties.get(
                                'api_version', constants.API_VER_NETWORK))
    # Get the existing probes
    lb_data = lb_iface.get(lb_name)
    lb_probes = lb_data.get('properties', dict()).get('probes', list())
    for idx, probe in enumerate(lb_probes):
        if probe.get('name') == utils.get_resource_name():
            del lb_probes[idx]
    # Update the Load Balancer with the new probes list
    utils.task_resource_update(lb_iface, {'properties': {
        'probes': lb_probes
    }},
                               name=lb_name)
示例#44
0
def get_connected_nsg():
    '''Finds a connected Network Security Group'''
    nsg = None
    nsg_name = None
    for rel in ctx.instance.relationships:
        if constants.REL_NIC_CONNECTED_TO_NSG in rel.type_hierarchy:
            nsg = NetworkSecurityGroup(_ctx=rel.target)
            nsg_name = utils.get_resource_name(rel.target)
    return {
        'id':
        '/subscriptions/{0}{1}/{2}'.format(
            utils.get_subscription_id(_ctx=nsg.ctx), nsg.endpoint, nsg_name)
    } if nsg else None
def get_connected_nsg():
    '''Finds a connected Network Security Group'''
    nsg = None
    nsg_name = None
    for rel in ctx.instance.relationships:
        if constants.REL_NIC_CONNECTED_TO_NSG in rel.type_hierarchy:
            nsg = NetworkSecurityGroup(_ctx=rel.target)
            nsg_name = utils.get_resource_name(rel.target)
    return {
        'id': '/subscriptions/{0}{1}/{2}'.format(
            utils.get_subscription_id(_ctx=nsg.ctx),
            nsg.endpoint,
            nsg_name)
    } if nsg else None
def build_ip_configuration(ipc):
    """
        Attempts to construct a proper IP Configuration from
        a context object

    :params `cloudify.context.RelationshipSubjectContext` ipc:
        IP Configuration context object
    :returns: IP Configuration dict
    :rtype: dict or None
    """
    if not ipc or not ipc.instance.relationships:
        return None
    # Find a referenced Subnet/PublicIPAddress
    rel_sub_type = constants.REL_IPC_CONNECTED_TO_SUBNET
    rel_pip_type = constants.REL_IPC_CONNECTED_TO_PUBIP
    subnet = None
    pubip = None
    for rel in ipc.instance.relationships:
        if isinstance(rel_sub_type, tuple):
            if any(x in rel.type_hierarchy for x in rel_sub_type):
                subnet = {
                    'id': rel.target.instance.runtime_properties['resource_id']
                }
        else:
            if rel_sub_type in rel.type_hierarchy:
                subnet = {
                    'id': rel.target.instance.runtime_properties['resource_id']
                }
        if isinstance(rel_pip_type, tuple):
            if any(x in rel.type_hierarchy for x in rel_pip_type):
                pubip = {
                    'id': rel.target.instance.runtime_properties['resource_id']
                }
        else:
            if rel_pip_type in rel.type_hierarchy:
                pubip = {
                    'id': rel.target.instance.runtime_properties['resource_id']
                }

    ip_configuration = {
        'name': utils.get_resource_name(ipc),
        'subnet': subnet,
        'public_ip_address': pubip
    }
    ip_configuration = \
        utils.handle_resource_config_params(ip_configuration,
                                            ipc.node.properties.get(
                                                "resource_config", {}))
    return ip_configuration
示例#47
0
def get_cloud_storage_account(_ctx=ctx):
    '''Gets the Azure Blob storage service'''
    # Get the storage account
    storage_account = utils.get_parent(_ctx.instance,
                                       rel_type=constants.REL_CONTAINED_IN_SA)
    storage_account_name = utils.get_resource_name(_ctx=storage_account)
    # Get the storage account keys
    keys = StorageAccount(_ctx=storage_account).list_keys()
    if not isinstance(keys, list) or len(keys) < 1:
        raise RecoverableError(
            'StorageAccount reported no usable authentication keys')
    # Get an interface to the Storage Account
    storage_account_key = keys[0].get('key')
    return CloudStorageAccount(account_name=storage_account_name,
                               account_key=storage_account_key)
示例#48
0
def attach_route_table(**_):
    '''Attaches a Route Table (source) to the Subnet (target)'''
    rtbl = RouteTable(_ctx=ctx.source)
    rtbl_name = utils.get_resource_name(ctx.source)
    # Attach
    utils.task_resource_update(
        Subnet(_ctx=ctx.target), {
            'properties': {
                'routeTable': {
                    'id': '/subscriptions/{0}{1}/{2}'.format(
                        utils.get_subscription_id(_ctx=ctx.source),
                        rtbl.endpoint,
                        rtbl_name)
                }
            }
        }, _ctx=ctx.target)
示例#49
0
def attach_network_security_group(**_):
    '''Attaches a Network Security Group (source) to the Subnet (target)'''
    nsg = NetworkSecurityGroup(_ctx=ctx.source)
    nsg_name = utils.get_resource_name(ctx.source)
    # Attach
    utils.task_resource_update(Subnet(_ctx=ctx.target), {
        'properties': {
            'networkSecurityGroup': {
                'id':
                '/subscriptions/{0}{1}/{2}'.format(
                    utils.get_subscription_id(_ctx=ctx.source), nsg.endpoint,
                    nsg_name)
            }
        }
    },
                               _ctx=ctx.target)
示例#50
0
def attach_network_security_group(**_):
    '''Attaches a Network Security Group (source) to the Subnet (target)'''
    nsg = NetworkSecurityGroup(_ctx=ctx.source)
    nsg_name = utils.get_resource_name(ctx.source)
    # Attach
    utils.task_resource_update(
        Subnet(_ctx=ctx.target), {
            'properties': {
                'networkSecurityGroup': {
                    'id': '/subscriptions/{0}{1}/{2}'.format(
                        utils.get_subscription_id(_ctx=ctx.source),
                        nsg.endpoint,
                        nsg_name)
                }
            }
        }, _ctx=ctx.target)
def get_cloud_storage_account(_ctx=ctx):
    '''Gets the Azure Blob storage service'''
    # Get the storage account
    storage_account = utils.get_parent(
        _ctx.instance,
        rel_type=constants.REL_CONTAINED_IN_SA)
    storage_account_name = utils.get_resource_name(_ctx=storage_account)
    # Get the storage account keys
    keys = StorageAccount(_ctx=storage_account).list_keys()
    if not isinstance(keys, list) or len(keys) < 1:
        raise RecoverableError(
            'StorageAccount reported no usable authentication keys')
    # Get an interface to the Storage Account
    storage_account_key = keys[0].get('key')
    return CloudStorageAccount(
        account_name=storage_account_name,
        account_key=storage_account_key)
def configure(command_to_execute, file_uris, **_):
    '''Configures the resource'''
    os_family = ctx.node.properties.get('os_family', '').lower()
    if os_family == 'windows':
        # By default, this should enable WinRM HTTP (unencrypted)
        # This entire function can be overridden from the plugin
        utils.task_resource_create(
            VirtualMachineExtension(
                virtual_machine=utils.get_resource_name()
            ),
            {
                'location': ctx.node.properties.get('location'),
                'tags': ctx.node.properties.get('tags'),
                'properties': {
                    'publisher': 'Microsoft.Compute',
                    'type': 'CustomScriptExtension',
                    'typeHandlerVersion': '1.4',
                    'settings': {
                        'fileUris': file_uris,
                        'commandToExecute': command_to_execute
                    }
                }
            })

    # Write the IP address to runtime properties for the agent
    # Get a reference to the NIC
    rel_nic = utils.get_relationship_by_type(
        ctx.instance.relationships,
        constants.REL_CONNECTED_TO_NIC)
    # No NIC? Exit and hope the user doesn't plan to install an agent
    if not rel_nic:
        return
    # Get the NIC data from the API directly (because of IPConfiguration)
    nic = NetworkInterfaceCard(_ctx=rel_nic.target)
    nic_data = nic.get(utils.get_resource_name(rel_nic.target))
    # Iterate over each IPConfiguration entry
    for ip_cfg in nic_data.get(
            'properties', dict()).get(
                'ipConfigurations', list()):
        # Get the Private IP Address endpoint
        ctx.instance.runtime_properties['ip'] = \
            ip_cfg.get('properties', dict()).get('privateIPAddress')
        # Get the Public IP Address endpoint
        pubip_id = ip_cfg.get(
            'properties', dict()).get(
                'publicIPAddress', dict()).get('id')
        if isinstance(pubip_id, basestring):
            # use the ID to get the data on the public ip
            pubip = PublicIPAddress(_ctx=rel_nic.target)
            pubip.endpoint = '{0}{1}'.format(
                constants.CONN_API_ENDPOINT, pubip_id)
            pubip_data = pubip.get()
            if isinstance(pubip_data, dict):
                ctx.instance.runtime_properties['public_ip'] = \
                    pubip_data.get('properties', dict()).get('ipAddress')
    # See if the user wants to use the public IP as primary IP
    if ctx.node.properties.get('use_public_ip') and \
            ctx.instance.runtime_properties.get('public_ip'):
        ctx.instance.runtime_properties['ip'] = \
            ctx.instance.runtime_properties.get('public_ip')
    ctx.logger.info('OUTPUT {0}.{1} = "{2}"'.format(
        ctx.instance.id,
        'ip',
        ctx.instance.runtime_properties.get('ip')))
    ctx.logger.info('OUTPUT {0}.{1} = "{2}"'.format(
        ctx.instance.id,
        'public_ip',
        ctx.instance.runtime_properties.get('public_ip')))
def create(**_):
    '''Uses an existing, or creates a new, Virtual Machine'''
    # Generate a resource name (if needed)
    utils.generate_resource_name(
        VirtualMachine(),
        generator=vm_name_generator)
    res_cfg = utils.get_resource_config() or dict()
    # Build storage profile
    osdisk = build_osdisk_profile(
        res_cfg.get('storageProfile', dict()).get('osDisk', dict()))
    datadisks = build_datadisks_profile(
        res_cfg.get('storageProfile', dict()).get('dataDisks', list()))
    storage_profile = {
        'osDisk': osdisk,
        'dataDisks': datadisks
    }
    # Build the network profile
    network_profile = build_network_profile()
    # Build the OS profile
    os_family = ctx.node.properties.get('os_family', '').lower()
    os_profile = dict()
    # Set defaults for Windows installs to enable WinRM listener
    if os_family == 'windows' and \
            not res_cfg.get('osProfile', dict()).get('windowsConfiguration'):
        os_profile = {
            'windowsConfiguration': {
                # This is required for extension scripts to work
                'provisionVMAgent': True,
                'winRM': {
                    'listeners': [{
                        'protocol': 'Http',
                        'certificateUrl': None
                    }]
                }
            },
            'linuxConfiguration': None
        }
    elif not res_cfg.get('osProfile', dict()).get('linuxConfiguration'):
        os_profile = {
            'linuxConfiguration': {
                'disablePasswordAuthentication': False
            },
            'windowsConfiguration': None
        }
    # Set the computerName if it's not set already
    os_profile['computerName'] = \
        res_cfg.get(
            'osProfile', dict()
        ).get('computerName', utils.get_resource_name())
    # Create a resource (if necessary)
    utils.task_resource_create(
        VirtualMachine(),
        {
            'location': ctx.node.properties.get('location'),
            'tags': ctx.node.properties.get('tags'),
            'plan': ctx.node.properties.get('plan'),
            'properties': utils.dict_update(
                utils.get_resource_config(),
                {
                    'availabilitySet': utils.get_rel_id_reference(
                        AvailabilitySet,
                        constants.REL_CONNECTED_TO_AS),
                    'networkProfile': network_profile,
                    'storageProfile': storage_profile,
                    'osProfile': os_profile
                }
            )
        })
def create_file_share(**_):
    '''Creates an Azure File Share'''
    # Get resource config values
    res_cfg = utils.get_resource_config() or dict()
    share_name = ctx.node.properties.get('name')
    metadata = res_cfg.get('metadata')
    quota = res_cfg.get('quota')
    fail_on_exist = res_cfg.get('fail_on_exist', False)
    # Check if invalid external resource
    if ctx.node.properties.get('use_external_resource', False) and \
       not share_name:
        raise NonRecoverableError(
            '"use_external_resource" specified without a resource "name"')
    # Get the storage account
    storage_account = utils.get_parent(
        ctx.instance,
        rel_type=constants.REL_CONTAINED_IN_SA)
    storage_account_name = utils.get_resource_name(_ctx=storage_account)
    # Get the storage account keys
    keys = StorageAccount(_ctx=storage_account).list_keys()
    if not isinstance(keys, list) or len(keys) < 1:
        raise RecoverableError(
            'StorageAccount reported no usable authentication keys')
    # Get an interface to the Storage Account
    storage_account_key = keys[0].get('key')
    storageacct = CloudStorageAccount(
        account_name=storage_account_name,
        account_key=storage_account_key)
    # Get an interface to the File Service
    filesvc = storageacct.create_file_service()
    if ctx.node.properties.get('use_external_resource', False):
        # Attempt to use an existing File Share (if specified)
        ctx.logger.debug('Checking for existing File Share "{0}"'
                         .format(share_name))
        try:
            share = filesvc.get_share_properties(share_name)
            metadata = share.get('metadata', dict())
            quota = share.get('properties', dict()).get('quota')
            created = False
        except Exception as ex:
            ctx.logger.error('File Share "{0}" does not exist and '
                             '"use_external_resource" is set to true'
                             .format(share_name))
            raise NonRecoverableError(ex)
    else:
        # Generate a new File Share name if needed
        if not share_name:
            ctx.logger.info('Generating a new File Share name')
            for _ in xrange(0, 10):
                tmpname = file_share_name_generator()
                if not file_share_exists(filesvc, tmpname):
                    share_name = tmpname
                    break
        # Handle name error
        if not share_name:
            raise NonRecoverableError(
                'Error generating a new File Share name. Failed '
                'after 10 tries.')
        # Attempt to create the File Share
        ctx.logger.debug('Creating File Share "{0}"'.format(share_name))
        created = filesvc.create_share(
            share_name=share_name,
            metadata=metadata,
            quota=quota,
            fail_on_exist=False)
        if not created:
            ctx.logger.warn('File Share already exists')
            if fail_on_exist:
                raise NonRecoverableError(
                    'File Share already exists in the storage account and '
                    '"fail_on_exist" set to True')
    # Set run-time properties
    ctx.instance.runtime_properties['name'] = share_name
    ctx.instance.runtime_properties['quota'] = quota
    ctx.instance.runtime_properties['metadata'] = metadata
    ctx.instance.runtime_properties['created'] = created
    ctx.instance.runtime_properties['storage_account'] = storage_account_name
    ctx.instance.runtime_properties['username'] = storage_account_name
    ctx.instance.runtime_properties['password'] = storage_account_key
    ctx.instance.runtime_properties['uri'] = '{0}.file.{1}/{2}'.format(
        storage_account_name, constants.CONN_STORAGE_FILE_ENDPOINT, share_name
    )
def configure(command_to_execute, file_uris, type_handler_version='v2.0', **_):
    '''Configures the resource'''
    os_family = ctx.node.properties.get('os_family', '').lower()
    if os_family == 'windows':
        utils.task_resource_create(
            VirtualMachineExtension(
                virtual_machine=utils.get_resource_name(),
                api_version=ctx.node.properties.get('api_version',
                                                    constants.API_VER_COMPUTE)
            ),
            {
                'location': ctx.node.properties.get('location'),
                'tags': ctx.node.properties.get('tags'),
                'properties': {
                    'publisher': 'Microsoft.Compute',
                    'type': 'CustomScriptExtension',
                    'typeHandlerVersion': type_handler_version,
                    'settings': {
                        'fileUris': file_uris,
                        'commandToExecute': command_to_execute
                    }
                }
            })

    virtual_machine_name = ctx.instance.runtime_properties.get('name')
    virtual_machine_iface = \
        VirtualMachine(
            api_version=ctx.node.properties.get(
                'api_version',
                constants.API_VER_COMPUTE)).get(
                    name=virtual_machine_name)

    # Write the IP address to runtime properties for the agent
    # Get a reference to the NIC
    rel_nics = utils.get_relationships_by_type(
        ctx.instance.relationships,
        constants.REL_CONNECTED_TO_NIC)

    # No NIC? Exit and hope the user doesn't plan to install an agent
    if not rel_nics:
        return

    for rel_nic in rel_nics:
        # Get the NIC data from the API directly (because of IPConfiguration)
        nic_iface = NetworkInterfaceCard(
            _ctx=rel_nic.target,
            api_version=rel_nic.target.node.properties.get(
                'api_version',
                constants.API_VER_NETWORK))
        nic_name = utils.get_resource_name(rel_nic.target)
        nic_data = nic_iface.get(nic_name)
        nic_virtual_machine_id = nic_data.get(
            'properties', dict()).get(
                'virtualMachine', dict()).get('id')

        if virtual_machine_name not in nic_virtual_machine_id:
            nic_data['properties'] = \
                utils.dict_update(
                    nic_data.get('properties', {}),
                    {
                        'virtualMachine': {
                            'id': virtual_machine_iface.get('id')
                        }
                    }
                )
            utils.task_resource_update(
                nic_iface, nic_data, _ctx=rel_nic.target)
            nic_data = nic_iface.get(nic_name)
            if virtual_machine_name not in nic_data.get(
                    'properties', dict()).get(
                        'virtualMachine', dict()).get('id', str()):
                return ctx.operation.retry(
                    message='Waiting for NIC {0} to '
                            'attach to VM {1}..'
                            .format(nic_name,
                                    virtual_machine_name),
                    retry_after=10)

        # Iterate over each IPConfiguration entry
        creds = utils.get_credentials(_ctx=ctx)
        for ip_cfg in nic_data.get(
                'properties', dict()).get(
                    'ipConfigurations', list()):

            # Get the Private IP Address endpoint
            ctx.instance.runtime_properties['ip'] = \
                ip_cfg.get('properties', dict()).get('privateIPAddress')

            # Get the Public IP Address endpoint
            pubip_id = ip_cfg.get(
                'properties', dict()).get(
                    'publicIPAddress', dict()).get('id')
            if isinstance(pubip_id, basestring):
                # use the ID to get the data on the public ip
                pubip = PublicIPAddress(
                    _ctx=rel_nic.target,
                    api_version=rel_nic.target.node.properties.get(
                        'api_version',
                        constants.API_VER_NETWORK))
                pubip.endpoint = '{0}{1}'.format(
                    creds.endpoints_resource_manager, pubip_id)
                pubip_data = pubip.get()
                if isinstance(pubip_data, dict):
                    public_ip = \
                        pubip_data.get('properties', dict()).get('ipAddress')
                    # Maintained for backwards compatibility.
                    ctx.instance.runtime_properties['public_ip'] = \
                        public_ip
                    # For consistency with other plugins.
                    ctx.instance.runtime_properties[PUBLIC_IP_PROPERTY] = \
                        public_ip
                    # We should also consider that maybe there will be many
                    # public ip addresses.
                    public_ip_addresses = \
                        ctx.instance.runtime_properties.get(
                            PUBLIC_IP_PROPERTY, [])
                    if public_ip not in public_ip_addresses:
                        public_ip_addresses.append(public_ip)
                    ctx.instance.runtime_properties['public_ip_addresses'] = \
                        public_ip_addresses

        # See if the user wants to use the public IP as primary IP
        if ctx.node.properties.get('use_public_ip') and \
                ctx.instance.runtime_properties.get('public_ip'):
            ctx.instance.runtime_properties['ip'] = \
                ctx.instance.runtime_properties.get('public_ip')
        ctx.logger.info('OUTPUT {0}.{1} = "{2}"'.format(
            ctx.instance.id,
            'ip',
            ctx.instance.runtime_properties.get('ip')))
        ctx.logger.info('OUTPUT {0}.{1} = "{2}"'.format(
            ctx.instance.id,
            'public_ip',
            ctx.instance.runtime_properties.get('public_ip')))
def create(args=None, **_):
    '''Uses an existing, or creates a new, Virtual Machine'''
    # Generate a resource name (if needed)
    utils.generate_resource_name(
        VirtualMachine(api_version=ctx.node.properties.get(
            'api_version', constants.API_VER_COMPUTE)),
        generator=vm_name_generator)
    res_cfg = utils.get_resource_config(args=args) or dict()
    # Build storage profile
    osdisk = build_osdisk_profile(
        res_cfg.get('storageProfile', dict()).get('osDisk', dict()))
    datadisks = build_datadisks_profile(
        res_cfg.get('storageProfile', dict()).get('dataDisks', list()))
    storage_profile = {
        'osDisk': osdisk,
        'dataDisks': datadisks
    }
    # Build the network profile
    network_profile = build_network_profile()
    # Build the OS profile
    os_family = ctx.node.properties.get('os_family', '').lower()
    os_profile = dict()
    # Set defaults for Windows installs to enable WinRM listener
    if os_family == 'windows' and \
            not res_cfg.get('osProfile', dict()).get('windowsConfiguration'):
        os_profile = {
            'windowsConfiguration': {
                # This is required for extension scripts to work
                'provisionVMAgent': True,
                'winRM': {
                    'listeners': [{
                        'protocol': 'Http',
                        'certificateUrl': None
                    }]
                }
            },
            'linuxConfiguration': None
        }
    elif not res_cfg.get('osProfile', dict()).get('linuxConfiguration'):
        os_profile = {
            'linuxConfiguration': {
                'disablePasswordAuthentication': False
            },
            'windowsConfiguration': None
        }
    # Set the computerName if it's not set already
    os_profile['computerName'] = \
        res_cfg.get(
            'osProfile', dict()
        ).get('computerName', utils.get_resource_name())

    resource_create_payload = \
        {
            'location': ctx.node.properties.get('location'),
            'tags': ctx.node.properties.get('tags'),
            'plan': ctx.node.properties.get('plan'),
            'properties': utils.dict_update(
                utils.get_resource_config(args=args),
                {
                    'availabilitySet': utils.get_rel_id_reference(
                        AvailabilitySet,
                        constants.REL_CONNECTED_TO_AS),
                    'networkProfile': network_profile,
                    'storageProfile': storage_profile,
                    'osProfile': os_profile
                }
            )
        }
    # support userdata from args.
    os_profile = resource_create_payload['properties']['osProfile']
    userdata = _handle_userdata(os_profile.get('customData'))
    if userdata:
        ctx.logger.warn(
            'Azure customData implementation is dependent on '
            'Virtual Machine image support.')
        os_profile['customData'] = base64.b64encode(userdata.encode())
    # Remove customData from osProfile if empty to avoid 400 Error.
    elif 'customData' in resource_create_payload['properties']['osProfile']:
        del resource_create_payload['properties']['osProfile']['customData']
    # Create a resource (if necessary)
    utils.task_resource_create(VirtualMachine(
        api_version=ctx.node.properties.get(
            'api_version', constants.API_VER_COMPUTE)),
        resource_create_payload)