def configure(**_): ''' 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) utils.task_resource_create( NetworkInterfaceCard(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(), { 'networkSecurityGroup': get_connected_nsg(), 'ipConfigurations': get_ip_configurations() }) })
def create(**_): '''Uses an existing, or creates a new, Resource Group''' # Create a resource (if necessary) utils.task_resource_create( ResourceGroup(), { 'location': ctx.node.properties.get('location'), 'tags': ctx.node.properties.get('tags') })
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(**_): '''Uses an existing, or creates a new, Resource Group''' # Create a resource (if necessary) utils.task_resource_create( ResourceGroup(api_version=ctx.node.properties.get( 'api_version', constants.API_VER_RESOURCES)), { 'location': ctx.node.properties.get('location'), 'tags': ctx.node.properties.get('tags') })
def create(**_): '''Uses an existing, or creates a new, Public IP Address''' # Create a resource (if necessary) utils.task_resource_create( PublicIPAddress(), { 'location': ctx.node.properties.get('location'), 'tags': ctx.node.properties.get('tags'), 'properties': utils.get_resource_config() })
def create(**_): '''Uses an existing, or creates a new, Virtual Network''' # Create a resource (if necessary) utils.task_resource_create( VirtualNetwork(), { 'location': ctx.node.properties.get('location'), 'tags': ctx.node.properties.get('tags'), 'properties': utils.get_resource_config() })
def create(**_): '''Uses an existing, or creates a new, Availability Set''' # Create a resource (if necessary) utils.task_resource_create( AvailabilitySet(), { 'location': ctx.node.properties.get('location'), 'tags': ctx.node.properties.get('tags'), 'properties': utils.get_resource_config() })
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 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 create(**_): '''Uses an existing, or creates a new, Public IP Address''' # Create a resource (if necessary) utils.task_resource_create( PublicIPAddress(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.get_resource_config() })
def create(**_): '''Uses an existing, or creates a new, Availability Set''' # Create a resource (if necessary) utils.task_resource_create( AvailabilitySet(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': utils.get_resource_config() })
def create(**_): '''Uses an existing, or creates a new, Network Security Group''' # Create a resource (if necessary) utils.task_resource_create( NetworkSecurityGroup(), { 'location': ctx.node.properties.get('location'), 'tags': ctx.node.properties.get('tags'), 'properties': utils.get_resource_config() })
def create(**_): '''Uses an existing, or creates a new, Storage Account''' # Generate a resource name (if needed) utils.generate_resource_name(StorageAccount(), generator=sa_name_generator) # Create a resource (if necessary) utils.task_resource_create( StorageAccount(), { 'location': ctx.node.properties.get('location'), 'tags': ctx.node.properties.get('tags'), 'properties': utils.get_resource_config() })
def create(**_): '''Uses an existing, or creates a new, Network Security Group''' # Create a resource (if necessary) utils.task_resource_create( NetworkSecurityGroup(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.get_resource_config() })
def create(**_): '''Uses an existing, or creates a new, Storage Account''' # Generate a resource name (if needed) utils.generate_resource_name( StorageAccount(), generator=sa_name_generator) # Create a resource (if necessary) utils.task_resource_create( StorageAccount(), { 'location': ctx.node.properties.get('location'), 'tags': ctx.node.properties.get('tags'), 'properties': utils.get_resource_config() })
def create(resource_config, **_): '''Uses an existing, or creates a new, Virtual Machine Extension''' # Work around for the reserved "type" name props = resource_config if 'ext_type' in props: props['type'] = props['ext_type'] del props['ext_type'] # Create a resource (if necessary) utils.task_resource_create( VirtualMachineExtension(), { 'location': ctx.node.properties.get('location'), 'tags': ctx.node.properties.get('tags'), 'properties': props })
def create(**_): '''Uses an existing, or creates a new, Storage Account''' # Generate a resource name (if needed) utils.generate_resource_name( StorageAccount(api_version=ctx.node.properties.get( 'api_version', constants.API_VER_STORAGE)), generator=sa_name_generator) sa_sku = ctx.node.properties.get('sku') sa_params = { 'location': ctx.node.properties.get('location'), 'tags': ctx.node.properties.get('tags'), 'properties': utils.get_resource_config() } if sa_sku: sa_params['sku'] = sa_sku # Create a resource (if necessary) utils.task_resource_create( StorageAccount(api_version=ctx.node.properties.get( 'api_version', constants.API_VER_STORAGE)), sa_params)
def create(resource_config, **_): '''Uses an existing, or creates a new, Virtual Machine Extension''' # Work around for the reserved "type" name props = resource_config if 'ext_type' in props: props['type'] = props['ext_type'] del props['ext_type'] # Create a resource (if necessary) ctx.logger.warn( 'Azure customData implementation is dependent on ' 'Virtual Machine image support.') utils.task_resource_create( VirtualMachineExtension(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': props })
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 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)
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)
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')))