def request_instance(vm_):
    '''
    Request a single GCE instance from a data dict.

    .. versionchanged: 2017.7.0
    '''
    if not GCE_VM_NAME_REGEX.match(vm_['name']):
        raise SaltCloudSystemExit(
            'VM names must start with a letter, only contain letters, numbers, or dashes '
            'and cannot end in a dash.'
        )

    try:
        # Check for required profile parameters before sending any API calls.
        if vm_['profile'] and config.is_profile_configured(__opts__,
                                                           __active_provider_name__ or 'gce',
                                                           vm_['profile'],
                                                           vm_=vm_) is False:
            return False
    except AttributeError:
        pass

    __utils__['cloud.fire_event'](
        'event',
        'create instance',
        'salt/cloud/{0}/creating'.format(vm_['name']),
        args=__utils__['cloud.filter_event']('creating', vm_, ['name', 'profile', 'provider', 'driver']),
        sock_dir=__opts__['sock_dir'],
        transport=__opts__['transport']
    )

    conn = get_conn()

    kwargs = {
        'name': vm_['name'],
        'size': __get_size(conn, vm_),
        'image': __get_image(conn, vm_),
        'location': __get_location(conn, vm_),
        'ex_network': __get_network(conn, vm_),
        'ex_subnetwork': __get_subnetwork(vm_),
        'ex_tags': __get_tags(vm_),
        'ex_metadata': __get_metadata(vm_),
    }
    external_ip = config.get_cloud_config_value(
        'external_ip', vm_, __opts__, default='ephemeral'
    )

    if external_ip.lower() == 'ephemeral':
        external_ip = 'ephemeral'
        vm_['external_ip'] = external_ip
    elif external_ip == 'None':
        external_ip = None
        vm_['external_ip'] = external_ip
    else:
        region = __get_region(conn, vm_)
        external_ip = __create_orget_address(conn, external_ip, region)
        vm_['external_ip'] = {
            'name': external_ip.name,
            'address': external_ip.address,
            'region': external_ip.region.name
        }
    kwargs['external_ip'] = external_ip

    if LIBCLOUD_VERSION_INFO > (0, 15, 1):

        kwargs.update({
            'ex_disk_type': config.get_cloud_config_value(
                'ex_disk_type', vm_, __opts__, default='pd-standard'),
            'ex_disk_auto_delete': config.get_cloud_config_value(
                'ex_disk_auto_delete', vm_, __opts__, default=True),
            'ex_disks_gce_struct': config.get_cloud_config_value(
                'ex_disks_gce_struct', vm_, __opts__, default=None),
            'ex_service_accounts': config.get_cloud_config_value(
                'ex_service_accounts', vm_, __opts__, default=None),
            'ex_can_ip_forward': config.get_cloud_config_value(
                'ip_forwarding', vm_, __opts__, default=False),
            'ex_preemptible': config.get_cloud_config_value(
                'preemptible', vm_, __opts__, default=False)
        })
        if kwargs.get('ex_disk_type') not in ('pd-standard', 'pd-ssd'):
            raise SaltCloudSystemExit(
                'The value of \'ex_disk_type\' needs to be one of: '
                '\'pd-standard\', \'pd-ssd\''
            )

    # GCE accelerator options are only supported as of libcloud >= 2.3.0
    # and Python 3+ is required so that libcloud will detect a type of
    # 'string' rather than 'unicode'
    if LIBCLOUD_VERSION_INFO >= (2, 3, 0) and isinstance(u'test', str):

        kwargs.update({
            'ex_accelerator_type': config.get_cloud_config_value(
                'ex_accelerator_type', vm_, __opts__, default=None),
            'ex_accelerator_count': config.get_cloud_config_value(
                'ex_accelerator_count', vm_, __opts__, default=None)
        })
        if kwargs.get('ex_accelerator_type'):
            log.warning(
                'An accelerator is being attached to this instance, '
                'the ex_on_host_maintenance setting is being set to '
                '\'TERMINATE\' as a result'
            )
            kwargs.update({
                'ex_on_host_maintenance': 'TERMINATE'
            })

    log.info(
        'Creating GCE instance %s in %s',
        vm_['name'], kwargs['location'].name
    )
    log.debug('Create instance kwargs %s', kwargs)

    __utils__['cloud.fire_event'](
        'event',
        'requesting instance',
        'salt/cloud/{0}/requesting'.format(vm_['name']),
        args=__utils__['cloud.filter_event']('requesting', vm_, ['name', 'profile', 'provider', 'driver']),
        sock_dir=__opts__['sock_dir'],
        transport=__opts__['transport']
    )

    try:
        node_data = conn.create_node(**kwargs)
    except Exception as exc:  # pylint: disable=W0703
        log.error(
            'Error creating %s on GCE\n\n'
            'The following exception was thrown by libcloud when trying to '
            'run the initial deployment: \n%s',
            vm_['name'], exc, exc_info_on_loglevel=logging.DEBUG
        )
        return False

    volumes = config.get_cloud_config_value(
        'volumes', vm_, __opts__, search_global=True
    )

    if volumes:
        __utils__['cloud.fire_event'](
            'event',
            'attaching volumes',
            'salt/cloud/{0}/attaching_volumes'.format(vm_['name']),
            args={'volumes': volumes},
            sock_dir=__opts__['sock_dir'],
            transport=__opts__['transport']
        )

        log.info('Create and attach volumes to node %s', vm_['name'])
        create_attach_volumes(
            vm_['name'],
            {
                'volumes': volumes,
                'node': node_data
            },
            call='action'
        )

    try:
        node_dict = show_instance(node_data['name'], 'action')
    except TypeError:
        # node_data is a libcloud Node which is unsubscriptable
        node_dict = show_instance(node_data.name, 'action')

    return node_dict, node_data
def request_instance ( vm_ ) : if not GCE_VM_NAME_REGEX . match ( vm_ [ 'name' ] ) : raise SaltCloudSystemExit ( 'VM names must start with a letter, only contain letters, numbers, or dashes ' 'and cannot end in a dash.' ) try : if vm_ [ 'profile' ] and config . is_profile_configured ( __opts__ , __active_provider_name__ or 'gce' , vm_ [ 'profile' ] , vm_ = vm_ ) is False : return False except AttributeError : pass __utils__ [ 'cloud.fire_event' ] ( 'event' , 'create instance' , 'salt/cloud/{0}/creating' . format ( vm_ [ 'name' ] ) , args = __utils__ [ 'cloud.filter_event' ] ( 'creating' , vm_ , [ 'name' , 'profile' , 'provider' , 'driver' ] ) , sock_dir = __opts__ [ 'sock_dir' ] , transport = __opts__ [ 'transport' ] ) conn = get_conn ( ) kwargs = { 'name' : vm_ [ 'name' ] , 'size' : __get_size ( conn , vm_ ) , 'image' : __get_image ( conn , vm_ ) , 'location' : __get_location ( conn , vm_ ) , 'ex_network' : __get_network ( conn , vm_ ) , 'ex_subnetwork' : __get_subnetwork ( vm_ ) , 'ex_tags' : __get_tags ( vm_ ) , 'ex_metadata' : __get_metadata ( vm_ ) , } external_ip = config . get_cloud_config_value ( 'external_ip' , vm_ , __opts__ , default = 'ephemeral' ) if external_ip . lower ( ) == 'ephemeral' : external_ip = 'ephemeral' vm_ [ 'external_ip' ] = external_ip elif external_ip == 'None' : external_ip = None vm_ [ 'external_ip' ] = external_ip else : region = __get_region ( conn , vm_ ) external_ip = __create_orget_address ( conn , external_ip , region ) vm_ [ 'external_ip' ] = { 'name' : external_ip . name , 'address' : external_ip . address , 'region' : external_ip . region . name } kwargs [ 'external_ip' ] = external_ip if LIBCLOUD_VERSION_INFO > ( 0 , 15 , 1 ) : kwargs . update ( { 'ex_disk_type' : config . get_cloud_config_value ( 'ex_disk_type' , vm_ , __opts__ , default = 'pd-standard' ) , 'ex_disk_auto_delete' : config . get_cloud_config_value ( 'ex_disk_auto_delete' , vm_ , __opts__ , default = True ) , 'ex_disks_gce_struct' : config . get_cloud_config_value ( 'ex_disks_gce_struct' , vm_ , __opts__ , default = None ) , 'ex_service_accounts' : config . get_cloud_config_value ( 'ex_service_accounts' , vm_ , __opts__ , default = None ) , 'ex_can_ip_forward' : config . get_cloud_config_value ( 'ip_forwarding' , vm_ , __opts__ , default = False ) , 'ex_preemptible' : config . get_cloud_config_value ( 'preemptible' , vm_ , __opts__ , default = False ) } ) if kwargs . get ( 'ex_disk_type' ) not in ( 'pd-standard' , 'pd-ssd' ) : raise SaltCloudSystemExit ( 'The value of \'ex_disk_type\' needs to be one of: ' '\'pd-standard\', \'pd-ssd\'' ) if LIBCLOUD_VERSION_INFO >= ( 2 , 3 , 0 ) and isinstance ( u'test' , str ) : kwargs . update ( { 'ex_accelerator_type' : config . get_cloud_config_value ( 'ex_accelerator_type' , vm_ , __opts__ , default = None ) , 'ex_accelerator_count' : config . get_cloud_config_value ( 'ex_accelerator_count' , vm_ , __opts__ , default = None ) } ) if kwargs . get ( 'ex_accelerator_type' ) : log . warning ( 'An accelerator is being attached to this instance, ' 'the ex_on_host_maintenance setting is being set to ' '\'TERMINATE\' as a result' ) kwargs . update ( { 'ex_on_host_maintenance' : 'TERMINATE' } ) log . info ( 'Creating GCE instance %s in %s' , vm_ [ 'name' ] , kwargs [ 'location' ] . name ) log . debug ( 'Create instance kwargs %s' , kwargs ) __utils__ [ 'cloud.fire_event' ] ( 'event' , 'requesting instance' , 'salt/cloud/{0}/requesting' . format ( vm_ [ 'name' ] ) , args = __utils__ [ 'cloud.filter_event' ] ( 'requesting' , vm_ , [ 'name' , 'profile' , 'provider' , 'driver' ] ) , sock_dir = __opts__ [ 'sock_dir' ] , transport = __opts__ [ 'transport' ] ) try : node_data = conn . create_node ( ** kwargs ) except Exception as exc : log . error ( 'Error creating %s on GCE\n\n' 'The following exception was thrown by libcloud when trying to ' 'run the initial deployment: \n%s' , vm_ [ 'name' ] , exc , exc_info_on_loglevel = logging . DEBUG ) return False volumes = config . get_cloud_config_value ( 'volumes' , vm_ , __opts__ , search_global = True ) if volumes : __utils__ [ 'cloud.fire_event' ] ( 'event' , 'attaching volumes' , 'salt/cloud/{0}/attaching_volumes' . format ( vm_ [ 'name' ] ) , args = { 'volumes' : volumes } , sock_dir = __opts__ [ 'sock_dir' ] , transport = __opts__ [ 'transport' ] ) log . info ( 'Create and attach volumes to node %s' , vm_ [ 'name' ] ) create_attach_volumes ( vm_ [ 'name' ] , { 'volumes' : volumes , 'node' : node_data } , call = 'action' ) try : node_dict = show_instance ( node_data [ 'name' ] , 'action' ) except TypeError : node_dict = show_instance ( node_data . name , 'action' ) return node_dict , node_data
Request a single GCE instance from a data dict.

    .. versionchanged: 2017.7.0