Perform an action on a VM which may be specific to this cloud provider
761997
def do_action(self, names, kwargs):
        '''
        
        '''
        ret = {}
        invalid_functions = {}
        names = set(names)

        for alias, drivers in six.iteritems(self.map_providers_parallel()):
            if not names:
                break
            for driver, vms in six.iteritems(drivers):
                if not names:
                    break
                valid_function = True
                fun = '{0}.{1}'.format(driver, self.opts['action'])
                if fun not in self.clouds:
                    log.info('\'%s()\' is not available. Not actioning...', fun)
                    valid_function = False
                for vm_name, vm_details in six.iteritems(vms):
                    if not names:
                        break
                    if vm_name not in names:
                        if not isinstance(vm_details, dict):
                            vm_details = {}
                        if 'id' in vm_details and vm_details['id'] in names:
                            vm_name = vm_details['id']
                        else:
                            log.debug(
                                'vm:%s in provider:%s is not in name '
                                'list:\'%s\'', vm_name, driver, names
                            )
                            continue

                    # Build the dictionary of invalid functions with their associated VMs.
                    if valid_function is False:
                        if invalid_functions.get(fun) is None:
                            invalid_functions.update({fun: []})
                        invalid_functions[fun].append(vm_name)
                        continue

                    with salt.utils.context.func_globals_inject(
                        self.clouds[fun],
                        __active_provider_name__=':'.join([alias, driver])
                    ):
                        if alias not in ret:
                            ret[alias] = {}
                        if driver not in ret[alias]:
                            ret[alias][driver] = {}

                        # Clean kwargs of "__pub_*" data before running the cloud action call.
                        # Prevents calling positional "kwarg" arg before "call" when no kwarg
                        # argument is present in the cloud driver function's arg spec.
                        kwargs = salt.utils.args.clean_kwargs(**kwargs)

                        if kwargs:
                            ret[alias][driver][vm_name] = self.clouds[fun](
                                vm_name, kwargs, call='action'
                            )
                        else:
                            ret[alias][driver][vm_name] = self.clouds[fun](
                                vm_name, call='action'
                            )
                        names.remove(vm_name)

        # Set the return information for the VMs listed in the invalid_functions dict.
        missing_vms = set()
        if invalid_functions:
            ret['Invalid Actions'] = invalid_functions
            invalid_func_vms = set()
            for key, val in six.iteritems(invalid_functions):
                invalid_func_vms = invalid_func_vms.union(set(val))

            # Find the VMs that are in names, but not in set of invalid functions.
            missing_vms = names.difference(invalid_func_vms)
            if missing_vms:
                ret['Not Found'] = list(missing_vms)
                ret['Not Actioned/Not Running'] = list(names)

        if not names:
            return ret

        # Don't return missing VM information for invalid functions until after we've had a
        # Chance to return successful actions. If a function is valid for one driver, but
        # Not another, we want to make sure the successful action is returned properly.
        if missing_vms:
            return ret

        # If we reach this point, the Not Actioned and Not Found lists will be the same,
        # But we want to list both for clarity/consistency with the invalid functions lists.
        ret['Not Actioned/Not Running'] = list(names)
        ret['Not Found'] = list(names)
        return ret
762887
def create(vm_):
    '''
    
    '''
    try:
        # Check for required profile parameters before sending any API calls.
        if vm_['profile'] and config.is_profile_configured(__opts__,
                                                           __active_provider_name__ or 'azure',
                                                           vm_['profile'],
                                                           vm_=vm_) is False:
            return False
    except AttributeError:
        pass

    __utils__['cloud.fire_event'](
        'event',
        'starting create',
        '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']
    )

    log.info('Creating Cloud VM %s', vm_['name'])
    conn = get_conn()

    label = vm_.get('label', vm_['name'])
    service_name = vm_.get('service_name', vm_['name'])
    service_kwargs = {
        'service_name': service_name,
        'label': label,
        'description': vm_.get('desc', vm_['name']),
    }

    loc_error = False
    if 'location' in vm_:
        if 'affinity_group' in vm_:
            loc_error = True
        else:
            service_kwargs['location'] = vm_['location']
    elif 'affinity_group' in vm_:
        service_kwargs['affinity_group'] = vm_['affinity_group']
    else:
        loc_error = True

    if loc_error:
        raise SaltCloudSystemExit(
            'Either a location or affinity group must be specified, but not both'
        )

    ssh_port = config.get_cloud_config_value('port', vm_, __opts__,
                                             default=22, search_global=True)

    ssh_endpoint = azure.servicemanagement.ConfigurationSetInputEndpoint(
        name='SSH',
        protocol='TCP',
        port=ssh_port,
        local_port=22,
    )

    network_config = azure.servicemanagement.ConfigurationSet()
    network_config.input_endpoints.input_endpoints.append(ssh_endpoint)
    network_config.configuration_set_type = 'NetworkConfiguration'

    if 'win_username' in vm_:
        system_config = azure.servicemanagement.WindowsConfigurationSet(
            computer_name=vm_['name'],
            admin_username=vm_['win_username'],
            admin_password=vm_['win_password'],
        )

        smb_port = '445'
        if 'smb_port' in vm_:
            smb_port = vm_['smb_port']

        smb_endpoint = azure.servicemanagement.ConfigurationSetInputEndpoint(
            name='SMB',
            protocol='TCP',
            port=smb_port,
            local_port=smb_port,
        )

        network_config.input_endpoints.input_endpoints.append(smb_endpoint)

        # Domain and WinRM configuration not yet supported by Salt Cloud
        system_config.domain_join = None
        system_config.win_rm = None

    else:
        system_config = azure.servicemanagement.LinuxConfigurationSet(
            host_name=vm_['name'],
            user_name=vm_['ssh_username'],
            user_password=vm_['ssh_password'],
            disable_ssh_password_authentication=False,
        )

    # TODO: Might need to create a storage account
    media_link = vm_['media_link']
    # TODO: Probably better to use more than just the name in the media_link
    media_link += '/{0}.vhd'.format(vm_['name'])
    os_hd = azure.servicemanagement.OSVirtualHardDisk(vm_['image'], media_link)

    vm_kwargs = {
        'service_name': service_name,
        'deployment_name': service_name,
        'deployment_slot': vm_['slot'],
        'label': label,
        'role_name': vm_['name'],
        'system_config': system_config,
        'os_virtual_hard_disk': os_hd,
        'role_size': vm_['size'],
        'network_config': network_config,
    }

    if 'virtual_network_name' in vm_:
        vm_kwargs['virtual_network_name'] = vm_['virtual_network_name']
        if 'subnet_name' in vm_:
            network_config.subnet_names.append(vm_['subnet_name'])

    log.debug('vm_kwargs: %s', vm_kwargs)

    event_kwargs = {'service_kwargs': service_kwargs.copy(),
                    'vm_kwargs': vm_kwargs.copy()}
    del event_kwargs['vm_kwargs']['system_config']
    del event_kwargs['vm_kwargs']['os_virtual_hard_disk']
    del event_kwargs['vm_kwargs']['network_config']
    __utils__['cloud.fire_event'](
        'event',
        'requesting instance',
        'salt/cloud/{0}/requesting'.format(vm_['name']),
        args=__utils__['cloud.filter_event']('requesting', event_kwargs, list(event_kwargs)),
        sock_dir=__opts__['sock_dir'],
        transport=__opts__['transport']
    )
    log.debug('vm_kwargs: %s', vm_kwargs)

    # Azure lets you open winrm on a new VM
    # Can open up specific ports in Azure; but not on Windows
    try:
        conn.create_hosted_service(**service_kwargs)
    except AzureConflictHttpError:
        log.debug('Cloud service already exists')
    except Exception as exc:
        error = 'The hosted service name is invalid.'
        if error in six.text_type(exc):
            log.error(
                'Error creating %s on Azure.\n\n'
                'The hosted service name is invalid. The name can contain '
                'only letters, numbers, and hyphens. The name must start with '
                'a letter and must end with a letter or a number.',
                vm_['name'],
                # Show the traceback if the debug logging level is enabled
                exc_info_on_loglevel=logging.DEBUG
            )
        else:
            log.error(
                'Error creating %s on Azure\n\n'
                'The following exception was thrown when trying to '
                'run the initial deployment: \n%s',
                vm_['name'], exc,
                # Show the traceback if the debug logging level is enabled
                exc_info_on_loglevel=logging.DEBUG
            )
        return False
    try:
        result = conn.create_virtual_machine_deployment(**vm_kwargs)
        log.debug('Request ID for machine: %s', result.request_id)
        _wait_for_async(conn, result.request_id)
    except AzureConflictHttpError:
        log.debug('Conflict error. The deployment may already exist, trying add_role')
        # Deleting two useless keywords
        del vm_kwargs['deployment_slot']
        del vm_kwargs['label']
        del vm_kwargs['virtual_network_name']
        result = conn.add_role(**vm_kwargs)
        _wait_for_async(conn, result.request_id)
    except Exception as exc:
        error = 'The hosted service name is invalid.'
        if error in six.text_type(exc):
            log.error(
                'Error creating %s on Azure.\n\n'
                'The VM name is invalid. The name can contain '
                'only letters, numbers, and hyphens. The name must start with '
                'a letter and must end with a letter or a number.',
                vm_['name'],
                # Show the traceback if the debug logging level is enabled
                exc_info_on_loglevel=logging.DEBUG
            )
        else:
            log.error(
                'Error creating %s on Azure.\n\n'
                'The Virtual Machine could not be created. If you '
                'are using an already existing Cloud Service, '
                'make sure you set up the `port` variable corresponding '
                'to the SSH port exists and that the port number is not '
                'already in use.\nThe following exception was thrown when trying to '
                'run the initial deployment: \n%s',
                vm_['name'], exc,
                # Show the traceback if the debug logging level is enabled
                exc_info_on_loglevel=logging.DEBUG
            )
        return False

    def wait_for_hostname():
        '''
        Wait for the IP address to become available
        '''
        try:
            conn.get_role(service_name, service_name, vm_['name'])
            data = show_instance(vm_['name'], call='action')
            if 'url' in data and data['url'] != six.text_type(''):
                return data['url']
        except AzureMissingResourceHttpError:
            pass
        time.sleep(1)
        return False

    hostname = salt.utils.cloud.wait_for_fun(
        wait_for_hostname,
        timeout=config.get_cloud_config_value(
            'wait_for_fun_timeout', vm_, __opts__, default=15 * 60),
    )

    if not hostname:
        log.error('Failed to get a value for the hostname.')
        return False

    vm_['ssh_host'] = hostname.replace('http://', '').replace('/', '')
    vm_['password'] = config.get_cloud_config_value(
        'ssh_password', vm_, __opts__
    )
    ret = __utils__['cloud.bootstrap'](vm_, __opts__)

    # Attaching volumes
    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=__utils__['cloud.filter_event']('attaching_volumes', vm_, ['volumes']),
            sock_dir=__opts__['sock_dir'],
            transport=__opts__['transport']
        )

        log.info('Create and attach volumes to node %s', vm_['name'])
        created = create_attach_volumes(
            vm_['name'],
            {
                'volumes': volumes,
                'service_name': service_name,
                'deployment_name': vm_['name'],
                'media_link': media_link,
                'role_name': vm_['name'],
                'del_all_vols_on_destroy': vm_.get('set_del_all_vols_on_destroy', False)
            },
            call='action'
        )
        ret['Attached Volumes'] = created

    data = show_instance(vm_['name'], call='action')
    log.info('Created Cloud VM \'%s\'', vm_)
    log.debug('\'%s\' VM creation details:\n%s', vm_['name'], pprint.pformat(data))

    ret.update(data)

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

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

    __utils__['cloud.fire_event'](
        'event',
        'starting create',
        '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']
    )

    log.info('Creating Cloud VM %s', vm_['name'])

    try:
        data = create_node(vm_)
    except Exception as exc:
        log.error(
            'Error creating %s on PARALLELS\n\n'
            'The following exception was thrown when trying to '
            'run the initial deployment: \n%s',
            vm_['name'], exc,
            # Show the traceback if the debug logging level is enabled
            exc_info_on_loglevel=logging.DEBUG
        )
        return False

    name = vm_['name']
    if not wait_until(name, 'CREATED'):
        return {'Error': 'Unable to start {0}, command timed out'.format(name)}
    start(vm_['name'], call='action')

    if not wait_until(name, 'STARTED'):
        return {'Error': 'Unable to start {0}, command timed out'.format(name)}

    def __query_node_data(vm_name):
        data = show_instance(vm_name, call='action')
        if 'public-ip' not in data['network']:
            # Trigger another iteration
            return
        return data

    try:
        data = salt.utils.cloud.wait_for_ip(
            __query_node_data,
            update_args=(vm_['name'],),
            timeout=config.get_cloud_config_value(
                'wait_for_ip_timeout', vm_, __opts__, default=5 * 60),
            interval=config.get_cloud_config_value(
                'wait_for_ip_interval', vm_, __opts__, default=5),
        )
    except (SaltCloudExecutionTimeout, SaltCloudExecutionFailure) as exc:
        try:
            # It might be already up, let's destroy it!
            destroy(vm_['name'])
        except SaltCloudSystemExit:
            pass
        finally:
            raise SaltCloudSystemExit(six.text_type(exc))

    comps = data['network']['public-ip']['address'].split('/')
    public_ip = comps[0]

    vm_['ssh_host'] = public_ip
    ret = __utils__['cloud.bootstrap'](vm_, __opts__)

    log.info('Created Cloud VM \'%s\'', vm_['name'])
    log.debug(
        '\'%s\' VM creation details:\n%s',
        vm_['name'], pprint.pformat(data)
    )

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

    return data
919873
def execute_on_vm(vm, options)
      check_runable_on(vm)

      options     = options.clone
      _method     = options.delete(:_method)
      _rebootable = options.delete(:_rebootable)

      options = vm.config.vbguest.to_hash.merge(options)
      machine = VagrantVbguest::Machine.new(vm, options)
      status  = machine.state
      vm.env.ui.send((:ok == status ? :success : :warn), I18n.t("vagrant_vbguest.status.#{status}", machine.info))

      if _method != :status
        machine.send(_method)
      end

      reboot!(vm, options) if _rebootable && machine.reboot?
    rescue VagrantVbguest::Installer::NoInstallerFoundError => e
      vm.env.ui.error e.message
    end
1172010
def cli(env, **args):
    """"""

    vsi = SoftLayer.VSManager(env.client)
    _validate_args(env, args)
    create_args = _parse_create_args(env.client, args)
    test = args.get('test', False)
    do_create = not (args.get('export') or test)

    if do_create:
        if not (env.skip_confirmations or formatting.confirm(
                "This action will incur charges on your account. Continue?")):
            raise exceptions.CLIAbort('Aborting virtual server order.')

    if args.get('export'):
        export_file = args.pop('export')
        template.export_to_template(export_file, args, exclude=['wait', 'test'])
        env.fout('Successfully exported options to a template file.')

    else:
        result = vsi.order_guest(create_args, test)
        output = _build_receipt_table(result, args.get('billing'), test)

        if do_create:
            env.fout(_build_guest_table(result))
        env.fout(output)

        if args.get('wait'):
            virtual_guests = utils.lookup(result, 'orderDetails', 'virtualGuests')
            guest_id = virtual_guests[0]['id']
            click.secho("Waiting for %s to finish provisioning..." % guest_id, fg='green')
            ready = vsi.wait_for_ready(guest_id, args.get('wait') or 1)
            if ready is False:
                env.out(env.fmt(output))
                raise exceptions.CLIHalt(code=1)
999945
def run_profile(self, profile, names, vm_overrides=None):
        '''
        
        '''
        if profile not in self.opts['profiles']:
            msg = 'Profile {0} is not defined'.format(profile)
            log.error(msg)
            return {'Error': msg}

        ret = {}
        if not vm_overrides:
            vm_overrides = {}

        try:
            with salt.utils.files.fopen(self.opts['conf_file'], 'r') as mcc:
                main_cloud_config = salt.utils.yaml.safe_load(mcc)
            if not main_cloud_config:
                main_cloud_config = {}
        except KeyError:
            main_cloud_config = {}
        except IOError:
            main_cloud_config = {}

        if main_cloud_config is None:
            main_cloud_config = {}

        mapped_providers = self.map_providers_parallel()
        profile_details = self.opts['profiles'][profile]
        vms = {}
        for prov, val in six.iteritems(mapped_providers):
            prov_name = next(iter(val))
            for node in mapped_providers[prov][prov_name]:
                vms[node] = mapped_providers[prov][prov_name][node]
                vms[node]['provider'] = prov
                vms[node]['driver'] = prov_name
        alias, driver = profile_details['provider'].split(':')

        provider_details = self.opts['providers'][alias][driver].copy()
        del provider_details['profiles']

        for name in names:
            if name in vms:
                prov = vms[name]['provider']
                driv = vms[name]['driver']
                msg = '{0} already exists under {1}:{2}'.format(
                    name, prov, driv
                )
                log.error(msg)
                ret[name] = {'Error': msg}
                continue

            vm_ = self.vm_config(
                name,
                main_cloud_config,
                provider_details,
                profile_details,
                vm_overrides,
            )
            if self.opts['parallel']:
                process = multiprocessing.Process(
                    target=self.create,
                    args=(vm_,)
                )
                process.start()
                ret[name] = {
                    'Provisioning': 'VM being provisioned in parallel. '
                                    'PID: {0}'.format(process.pid)
                }
                continue

            try:
                # No need to inject __active_provider_name__ into the context
                # here because self.create takes care of that
                ret[name] = self.create(vm_)
                if not ret[name]:
                    ret[name] = {'Error': 'Failed to deploy VM'}
                    if len(names) == 1:
                        raise SaltCloudSystemExit('Failed to deploy VM')
                    continue
                if self.opts.get('show_deploy_args', False) is False:
                    ret[name].pop('deploy_kwargs', None)
            except (SaltCloudSystemExit, SaltCloudConfigError) as exc:
                if len(names) == 1:
                    raise
                ret[name] = {'Error': str(exc)}

        return ret
995965
def managedcloud(vm_):
    '''
    
    '''
    return config.get_cloud_config_value(
        'managedcloud', vm_, __opts__, default=False,
        search_global=False
    )
361730
def perform(action_name, container, **kwargs):
    
    cf = container_fabric()
    cf.call(action_name, container, **kwargs)
1365112
def _attach(cls, iface_id, vm_id):
        
        oper = cls.call('hosting.vm.iface_attach', vm_id, iface_id)
        return oper
73282
def create(vm_):
    '''
    
    '''
    try:
        # Check for required profile parameters before sending any API calls.
        if vm_['profile'] and config.is_profile_configured(__opts__,
                                                           __active_provider_name__ or 'joyent',
                                                           vm_['profile'],
                                                           vm_=vm_) is False:
            return False
    except AttributeError:
        pass

    key_filename = config.get_cloud_config_value(
        'private_key', vm_, __opts__, search_global=False, default=None
    )

    __utils__['cloud.fire_event'](
        'event',
        'starting create',
        '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']
    )

    log.info(
        'Creating Cloud VM %s in %s',
        vm_['name'], vm_.get('location', DEFAULT_LOCATION)
    )

    # added . for fqdn hostnames
    salt.utils.cloud.check_name(vm_['name'], 'a-zA-Z0-9-.')
    kwargs = {
        'name': vm_['name'],
        'image': get_image(vm_),
        'size': get_size(vm_),
        'location': vm_.get('location', DEFAULT_LOCATION)
    }
    # Let's not assign a default here; only assign a network value if
    # one is explicitly configured
    if 'networks' in vm_:
        kwargs['networks'] = vm_.get('networks')

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

    data = create_node(**kwargs)
    if data == {}:
        log.error('Error creating %s on JOYENT', vm_['name'])
        return False

    query_instance(vm_)
    data = show_instance(vm_['name'], call='action')

    vm_['key_filename'] = key_filename
    vm_['ssh_host'] = data[1]['primaryIp']

    __utils__['cloud.bootstrap'](vm_, __opts__)

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

    return data[1]
1084764
def show_instance(vm_name, call=None):
    '''
    
    '''
    if call != 'action':
        raise SaltCloudSystemExit(
            'The show_instance action must be called with -a or --action.'
        )
    conn = get_conn()
    node = _expand_node(conn.ex_get_node(vm_name))
    __utils__['cloud.cache_node'](node, __active_provider_name__, __opts__)
    return node
1340938
def create(vm_):
    '''
    
    '''
    try:
        # Check for required profile parameters before sending any API calls.
        if (vm_['profile'] and
            config.is_profile_configured(__opts__,
                                         __active_provider_name__ or 'vmware',
                                         vm_['profile'],
                                         vm_=vm_) is False):
            return False
    except AttributeError:
        pass

    __utils__['cloud.fire_event'](
        'event',
        'starting create',
        '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']
    )

    vm_name = config.get_cloud_config_value(
        'name', vm_, __opts__, default=None
    )
    folder = config.get_cloud_config_value(
        'folder', vm_, __opts__, default=None
    )
    datacenter = config.get_cloud_config_value(
        'datacenter', vm_, __opts__, default=None
    )
    resourcepool = config.get_cloud_config_value(
        'resourcepool', vm_, __opts__, default=None
    )
    cluster = config.get_cloud_config_value(
        'cluster', vm_, __opts__, default=None
    )
    datastore = config.get_cloud_config_value(
        'datastore', vm_, __opts__, default=None
    )
    host = config.get_cloud_config_value(
        'host', vm_, __opts__, default=None
    )
    template = config.get_cloud_config_value(
        'template', vm_, __opts__, default=False
    )
    num_cpus = config.get_cloud_config_value(
        'num_cpus', vm_, __opts__, default=None
    )
    cores_per_socket = config.get_cloud_config_value(
        'cores_per_socket', vm_, __opts__, default=None
    )
    memory = config.get_cloud_config_value(
        'memory', vm_, __opts__, default=None
    )
    devices = config.get_cloud_config_value(
        'devices', vm_, __opts__, default=None
    )
    extra_config = config.get_cloud_config_value(
        'extra_config', vm_, __opts__, default=None
    )
    annotation = config.get_cloud_config_value(
        'annotation', vm_, __opts__, default=None
    )
    power = config.get_cloud_config_value(
        'power_on', vm_, __opts__, default=True
    )
    key_filename = config.get_cloud_config_value(
        'private_key', vm_, __opts__, search_global=False, default=None
    )
    deploy = config.get_cloud_config_value(
        'deploy', vm_, __opts__, search_global=True, default=True
    )
    wait_for_ip_timeout = config.get_cloud_config_value(
        'wait_for_ip_timeout', vm_, __opts__, default=20 * 60
    )
    domain = config.get_cloud_config_value(
        'domain', vm_, __opts__, search_global=False, default='local'
    )
    hardware_version = config.get_cloud_config_value(
        'hardware_version', vm_, __opts__, search_global=False, default=None
    )
    guest_id = config.get_cloud_config_value(
        'image', vm_, __opts__, search_global=False, default=None
    )
    customization = config.get_cloud_config_value(
        'customization', vm_, __opts__, search_global=False, default=True
    )
    customization_spec = config.get_cloud_config_value(
        'customization_spec', vm_, __opts__, search_global=False, default=None
    )
    win_password = config.get_cloud_config_value(
        'win_password', vm_, __opts__, search_global=False, default=None
    )
    win_organization_name = config.get_cloud_config_value(
        'win_organization_name', vm_, __opts__, search_global=False, default='Organization'
    )
    plain_text = config.get_cloud_config_value(
        'plain_text', vm_, __opts__, search_global=False, default=False
    )
    win_user_fullname = config.get_cloud_config_value(
        'win_user_fullname', vm_, __opts__, search_global=False, default='Windows User'
    )
    win_run_once = config.get_cloud_config_value(
        'win_run_once', vm_, __opts__, search_global=False, default=None
    )
    win_ad_domain = config.get_cloud_config_value(
        'win_ad_domain', vm_, __opts__, search_global=False, default=''
    )
    win_ad_user = config.get_cloud_config_value(
        'win_ad_user', vm_, __opts__, search_global=False, default=''
    )
    win_ad_password = config.get_cloud_config_value(
        'win_ad_password', vm_, __opts__, search_global=False, default=''
    )
    win_autologon = config.get_cloud_config_value(
        'win_autologon', vm_, __opts__, search_global=False, default=True
    )
    timezone = config.get_cloud_config_value(
        'timezone', vm_, __opts__, search_global=False, default=''
    )
    hw_clock_utc = config.get_cloud_config_value(
        'hw_clock_utc', vm_, __opts__, search_global=False, default=''
    )
    clonefrom_datacenter = config.get_cloud_config_value(
        'clonefrom_datacenter', vm_, __opts__, search_global=False, default=datacenter
    )

    # Get service instance object
    si = _get_si()

    container_ref = None
    clonefrom_datacenter_ref = None

    # If datacenter is specified, set the container reference to start search from it instead
    if datacenter:
        datacenter_ref = salt.utils.vmware.get_mor_by_property(_get_si(), vim.Datacenter, datacenter)
        container_ref = datacenter_ref if datacenter_ref else None

    if 'clonefrom' in vm_:
        # If datacenter is specified, set the container reference to start search from it instead
        if datacenter:
            datacenter_ref = salt.utils.vmware.get_mor_by_property(
                                 si,
                                 vim.Datacenter,
                                 datacenter
                             )
            container_ref = datacenter_ref if datacenter_ref else None
            clonefrom_container_ref = datacenter_ref if datacenter_ref else None
        # allow specifying a different datacenter that the template lives in
        if clonefrom_datacenter:
            clonefrom_datacenter_ref = salt.utils.vmware.get_mor_by_property(
                                           si,
                                           vim.Datacenter,
                                           clonefrom_datacenter
                                       )
            clonefrom_container_ref = clonefrom_datacenter_ref if clonefrom_datacenter_ref else None

        # Clone VM/template from specified VM/template
        object_ref = salt.utils.vmware.get_mor_by_property(
                         si,
                         vim.VirtualMachine,
                         vm_['clonefrom'],
                         container_ref=clonefrom_container_ref
                     )
        if object_ref:
            clone_type = "template" if object_ref.config.template else "vm"
        else:
            raise SaltCloudSystemExit(
                'The VM/template that you have specified under clonefrom does not exist.'
            )
    else:
        clone_type = None
        object_ref = None

    # Either a cluster, or a resource pool must be specified when cloning from template or creating.
    if resourcepool:
        resourcepool_ref = salt.utils.vmware.get_mor_by_property(
                               si,
                               vim.ResourcePool,
                               resourcepool,
                               container_ref=container_ref
                           )
        if not resourcepool_ref:
            log.error("Specified resource pool: '%s' does not exist", resourcepool)
            if not clone_type or clone_type == "template":
                raise SaltCloudSystemExit('You must specify a resource pool that exists.')
    elif cluster:
        cluster_ref = salt.utils.vmware.get_mor_by_property(
                          si,
                          vim.ClusterComputeResource,
                          cluster,
                          container_ref=container_ref
                      )
        if not cluster_ref:
            log.error("Specified cluster: '%s' does not exist", cluster)
            if not clone_type or clone_type == "template":
                raise SaltCloudSystemExit('You must specify a cluster that exists.')
        else:
            resourcepool_ref = cluster_ref.resourcePool
    elif clone_type == "template":
        raise SaltCloudSystemExit(
            'You must either specify a cluster or a resource pool when cloning from a template.'
        )
    elif not clone_type:
        raise SaltCloudSystemExit(
            'You must either specify a cluster or a resource pool when creating.'
        )
    else:
        log.debug("Using resource pool used by the %s %s", clone_type, vm_['clonefrom'])

    # Either a datacenter or a folder can be optionally specified when cloning, required when creating.
    # If not specified when cloning, the existing VM/template\'s parent folder is used.
    if folder:
        folder_parts = folder.split('/')
        search_reference = container_ref
        for folder_part in folder_parts:
            if folder_part:
                folder_ref = salt.utils.vmware.get_mor_by_property(
                                 si,
                                 vim.Folder,
                                 folder_part,
                                 container_ref=search_reference
                             )
                search_reference = folder_ref
        if not folder_ref:
            log.error("Specified folder: '%s' does not exist", folder)
            log.debug("Using folder in which %s %s is present", clone_type, vm_['clonefrom'])
            folder_ref = object_ref.parent
    elif datacenter:
        if not datacenter_ref:
            log.error("Specified datacenter: '%s' does not exist", datacenter)
            log.debug("Using datacenter folder in which %s %s is present", clone_type, vm_['clonefrom'])
            folder_ref = object_ref.parent
        else:
            folder_ref = datacenter_ref.vmFolder
    elif not clone_type:
        raise SaltCloudSystemExit(
            'You must either specify a folder or a datacenter when creating not cloning.'
        )
    else:
        log.debug("Using folder in which %s %s is present", clone_type, vm_['clonefrom'])
        folder_ref = object_ref.parent

    if 'clonefrom' in vm_:
        # Create the relocation specs
        reloc_spec = vim.vm.RelocateSpec()

        if (resourcepool and resourcepool_ref) or (cluster and cluster_ref):
            reloc_spec.pool = resourcepool_ref

        # Either a datastore/datastore cluster can be optionally specified.
        # If not specified, the current datastore is used.
        if datastore:
            datastore_ref = salt.utils.vmware.get_mor_by_property(
                                si,
                                vim.Datastore,
                                datastore,
                                container_ref=container_ref
                            )
            if datastore_ref:
                # specific datastore has been specified
                reloc_spec.datastore = datastore_ref
            else:
                datastore_cluster_ref = salt.utils.vmware.get_mor_by_property(si, vim.StoragePod, datastore, container_ref=container_ref)
                if not datastore_cluster_ref:
                    log.error("Specified datastore/datastore cluster: '%s' does not exist", datastore)
                    log.debug("Using datastore used by the %s %s", clone_type, vm_['clonefrom'])
        else:
            log.debug("No datastore/datastore cluster specified")
            log.debug("Using datastore used by the %s %s", clone_type, vm_['clonefrom'])

        if host:
            host_ref = salt.utils.vmware.get_mor_by_property(
                           si,
                           vim.HostSystem,
                           host,
                           container_ref=container_ref
                       )
            if host_ref:
                reloc_spec.host = host_ref
            else:
                log.error("Specified host: '%s' does not exist", host)
    else:
        if not datastore:
            raise SaltCloudSystemExit(
                'You must specify a datastore when creating not cloning.'
            )
        else:
            datastore_ref = salt.utils.vmware.get_mor_by_property(
                                si,
                                vim.Datastore,
                                datastore
                            )
            if not datastore_ref:
                raise SaltCloudSystemExit("Specified datastore: '{0}' does not exist".format(datastore))

        if host:
            host_ref = salt.utils.vmware.get_mor_by_property(
                           _get_si(),
                           vim.HostSystem,
                           host,
                           container_ref=container_ref
                       )
            if not host_ref:
                log.error("Specified host: '%s' does not exist", host)

    # Create the config specs
    config_spec = vim.vm.ConfigSpec()

    # If the hardware version is specified and if it is different from the current
    # hardware version, then schedule a hardware version upgrade
    if hardware_version and object_ref is not None:
        hardware_version = 'vmx-{0:02}'.format(hardware_version)
        if hardware_version != object_ref.config.version:
            log.debug(
                "Scheduling hardware version upgrade from %s to %s",
                object_ref.config.version, hardware_version
            )
            scheduled_hardware_upgrade = vim.vm.ScheduledHardwareUpgradeInfo()
            scheduled_hardware_upgrade.upgradePolicy = 'always'
            scheduled_hardware_upgrade.versionKey = hardware_version
            config_spec.scheduledHardwareUpgradeInfo = scheduled_hardware_upgrade
        else:
            log.debug("Virtual hardware version already set to %s", hardware_version)

    if num_cpus:
        log.debug("Setting cpu to: %s", num_cpus)
        config_spec.numCPUs = int(num_cpus)

    if cores_per_socket:
        log.debug("Setting cores per socket to: %s", cores_per_socket)
        config_spec.numCoresPerSocket = int(cores_per_socket)

    if memory:
        try:
            memory_num, memory_unit = re.findall(r"[^\W\d_]+|\d+.\d+|\d+",
                                                 memory)
            if memory_unit.lower() == "mb":
                memory_mb = int(memory_num)
            elif memory_unit.lower() == "gb":
                memory_mb = int(float(memory_num)*1024.0)
            else:
                err_msg = "Invalid memory type specified: '{0}'".format(memory_unit)
                log.error(err_msg)
                return {'Error': err_msg}
        except (TypeError, ValueError):
            memory_mb = int(memory)
        log.debug("Setting memory to: %s MB", memory_mb)
        config_spec.memoryMB = memory_mb

    if devices:
        specs = _manage_devices(devices, vm=object_ref, container_ref=container_ref, new_vm_name=vm_name)
        config_spec.deviceChange = specs['device_specs']

    if extra_config:
        for key, value in six.iteritems(extra_config):
            option = vim.option.OptionValue(key=key, value=value)
            config_spec.extraConfig.append(option)

    if annotation:
        config_spec.annotation = six.text_type(annotation)

    if 'clonefrom' in vm_:
        clone_spec = handle_snapshot(
            config_spec,
            object_ref,
            reloc_spec,
            template,
            vm_
        )
        if not clone_spec:
            clone_spec = build_clonespec(config_spec,
                                         object_ref,
                                         reloc_spec,
                                         template)

        if customization and customization_spec:
            customization_spec = salt.utils.vmware.get_customizationspec_ref(si=si, customization_spec_name=customization_spec)
            clone_spec.customization = customization_spec.spec
        elif customization and (devices and 'network' in list(devices.keys())):
            global_ip = vim.vm.customization.GlobalIPSettings()
            if 'dns_servers' in list(vm_.keys()):
                global_ip.dnsServerList = vm_['dns_servers']

            non_hostname_chars = re.compile(r'[^\w-]')
            if re.search(non_hostname_chars, vm_name):
                host_name = re.split(non_hostname_chars,
                                     vm_name,
                                     maxsplit=1)[0]
                domain_name = re.split(non_hostname_chars,
                                       vm_name,
                                       maxsplit=1)[-1]
            else:
                host_name = vm_name
                domain_name = domain

            if 'Windows' not in object_ref.config.guestFullName:
                identity = vim.vm.customization.LinuxPrep()
                identity.hostName = vim.vm.customization.FixedName(name=host_name)
                identity.domain = domain_name
                if timezone:
                    identity.timeZone = timezone
                if isinstance(hw_clock_utc, bool):
                    identity.hwClockUTC = hw_clock_utc
            else:
                identity = vim.vm.customization.Sysprep()
                identity.guiUnattended = vim.vm.customization.GuiUnattended()
                identity.guiUnattended.autoLogon = win_autologon
                if win_autologon:
                    identity.guiUnattended.autoLogonCount = 1
                else:
                    identity.guiUnattended.autoLogonCount = 0
                identity.guiUnattended.password = vim.vm.customization.Password()
                identity.guiUnattended.password.value = win_password
                identity.guiUnattended.password.plainText = plain_text
                if timezone:
                    identity.guiUnattended.timeZone = timezone
                if win_run_once:
                    identity.guiRunOnce = vim.vm.customization.GuiRunOnce()
                    identity.guiRunOnce.commandList = win_run_once
                identity.userData = vim.vm.customization.UserData()
                identity.userData.fullName = win_user_fullname
                identity.userData.orgName = win_organization_name
                identity.userData.computerName = vim.vm.customization.FixedName()
                identity.userData.computerName.name = host_name
                identity.identification = vim.vm.customization.Identification()
                if win_ad_domain and win_ad_user and win_ad_password:
                    identity.identification.joinDomain = win_ad_domain
                    identity.identification.domainAdmin = win_ad_user
                    identity.identification.domainAdminPassword = vim.vm.customization.Password()
                    identity.identification.domainAdminPassword.value = win_ad_password
                    identity.identification.domainAdminPassword.plainText = plain_text
            custom_spec = vim.vm.customization.Specification(
                globalIPSettings=global_ip,
                identity=identity,
                nicSettingMap=specs['nics_map']
            )
            clone_spec.customization = custom_spec

        if not template:
            clone_spec.powerOn = power

        log.debug('clone_spec set to:\n%s', pprint.pformat(clone_spec))

    else:
        config_spec.name = vm_name
        config_spec.files = vim.vm.FileInfo()
        config_spec.files.vmPathName = '[{0}] {1}/{1}.vmx'.format(datastore, vm_name)
        config_spec.guestId = guest_id

        log.debug('config_spec set to:\n%s', pprint.pformat(config_spec))

    event_kwargs = vm_.copy()
    if event_kwargs.get('password'):
        del event_kwargs['password']

    try:
        __utils__['cloud.fire_event'](
            'event',
            'requesting instance',
            'salt/cloud/{0}/requesting'.format(vm_['name']),
            args=__utils__['cloud.filter_event']('requesting', event_kwargs, list(event_kwargs)),
            sock_dir=__opts__['sock_dir'],
            transport=__opts__['transport']
        )

        if 'clonefrom' in vm_:
            log.info("Creating %s from %s(%s)", vm_['name'], clone_type, vm_['clonefrom'])

            if datastore and not datastore_ref and datastore_cluster_ref:
                # datastore cluster has been specified so apply Storage DRS recommendations
                pod_spec = vim.storageDrs.PodSelectionSpec(storagePod=datastore_cluster_ref)

                storage_spec = vim.storageDrs.StoragePlacementSpec(
                    type='clone',
                    vm=object_ref,
                    podSelectionSpec=pod_spec,
                    cloneSpec=clone_spec,
                    cloneName=vm_name,
                    folder=folder_ref
                )

                # get recommended datastores
                recommended_datastores = si.content.storageResourceManager.RecommendDatastores(storageSpec=storage_spec)

                # apply storage DRS recommendations
                task = si.content.storageResourceManager.ApplyStorageDrsRecommendation_Task(recommended_datastores.recommendations[0].key)
                salt.utils.vmware.wait_for_task(task, vm_name, 'apply storage DRS recommendations', 5, 'info')
            else:
                # clone the VM/template
                task = object_ref.Clone(folder_ref, vm_name, clone_spec)
                salt.utils.vmware.wait_for_task(task, vm_name, 'clone', 5, 'info')
        else:
            log.info('Creating %s', vm_['name'])

            if host:
                task = folder_ref.CreateVM_Task(config_spec, resourcepool_ref, host_ref)
            else:
                task = folder_ref.CreateVM_Task(config_spec, resourcepool_ref)
            salt.utils.vmware.wait_for_task(task, vm_name, "create", 15, 'info')
    except Exception as exc:
        err_msg = 'Error creating {0}: {1}'.format(vm_['name'], exc)
        log.error(
            err_msg,
            # Show the traceback if the debug logging level is enabled
            exc_info_on_loglevel=logging.DEBUG
        )
        return {'Error': err_msg}

    new_vm_ref = salt.utils.vmware.get_mor_by_property(si, vim.VirtualMachine, vm_name, container_ref=container_ref)

    # Find how to power on in CreateVM_Task (if possible), for now this will do
    try:
        if not clone_type and power:
            task = new_vm_ref.PowerOn()
            salt.utils.vmware.wait_for_task(task, vm_name, 'power', 5, 'info')
    except Exception as exc:
        log.info('Powering on the VM threw this exception. Ignoring.')
        log.info(exc)

    # If it a template or if it does not need to be powered on then do not wait for the IP
    out = None
    if not template and power:
        ip = _wait_for_ip(new_vm_ref, wait_for_ip_timeout)
        if ip:
            log.info("[ %s ] IPv4 is: %s", vm_name, ip)
            # ssh or smb using ip and install salt only if deploy is True
            if deploy:
                vm_['key_filename'] = key_filename
                # if specified, prefer ssh_host to the discovered ip address
                if 'ssh_host' not in vm_:
                    vm_['ssh_host'] = ip
                log.info("[ %s ] Deploying to %s", vm_name, vm_['ssh_host'])

                out = __utils__['cloud.bootstrap'](vm_, __opts__)

    data = show_instance(vm_name, call='action')

    if deploy and isinstance(out, dict):
        data['deploy_kwargs'] = out.get('deploy_kwargs', {})

    __utils__['cloud.fire_event'](
        'event',
        'created instance',
        'salt/cloud/{0}/created'.format(vm_['name']),
        args=__utils__['cloud.filter_event']('created', vm_, ['name', 'profile', 'provider', 'driver']),
        sock_dir=__opts__['sock_dir'],
        transport=__opts__['transport']
    )
    return data
1166881
def suspend(name, call=None):
    '''
    
    '''
    if call != 'action':
        raise SaltCloudSystemExit(
            'The suspend action must be called with '
            '-a or --action.'
        )

    vm_properties = [
        "name",
        "summary.runtime.powerState"
    ]

    vm_list = salt.utils.vmware.get_mors_with_properties(_get_si(), vim.VirtualMachine, vm_properties)

    for vm in vm_list:
        if vm["name"] == name:
            if vm["summary.runtime.powerState"] == "poweredOff":
                ret = 'cannot suspend in powered off state'
                log.info('VM %s %s', name, ret)
                return ret
            elif vm["summary.runtime.powerState"] == "suspended":
                ret = 'already suspended'
                log.info('VM %s %s', name, ret)
                return ret
            try:
                log.info('Suspending VM %s', name)
                task = vm["object"].Suspend()
                salt.utils.vmware.wait_for_task(task, name, 'suspend')
            except Exception as exc:
                log.error(
                    'Error while suspending VM %s: %s',
                    name, exc,
                    # Show the traceback if the debug logging level is enabled
                    exc_info_on_loglevel=logging.DEBUG
                )
                return 'failed to suspend'

    return 'suspended'
380346
public static <T> T runInVm(PrivilegedExceptionAction<T> action) throws PrivilegedActionException {
        checkPermission(PERFORM_IN_VM_CALL);

        if (action == null) return null;
        Boolean originalValue = IN_VM_CALL.get();

        try {
            IN_VM_CALL.set(Boolean.TRUE);
            return action.run();
        } catch (RuntimeException | PrivilegedActionException e) {
            throw e;
        } catch (Exception e) {
            throw new PrivilegedActionException(e);
        } finally {
            IN_VM_CALL.set(originalValue);
        }
    }
383967
def pause(vm_):
    '''
    
    '''
    with _get_xapi_session() as xapi:
        vm_uuid = _get_label_uuid(xapi, 'VM', vm_)
        if vm_uuid is False:
            return False
        try:
            xapi.VM.pause(vm_uuid)
            return True
        except Exception:
            return False
18829
def _provision_vm(name=None, session=None):
    '''
    
    '''
    if session is None:
        session = _get_session()
    log.info('Provisioning VM %s', name)
    vm = _get_vm(name, session)
    task = session.xenapi.Async.VM.provision(vm)
    _run_async_task(task, session)
177539
def wait_for_instance(
        vm_=None,
        data=None,
        ip_address=None,
        display_ssh_output=True,
        call=None,
    ):
    '''
    
    '''
    if call == 'function':
        # Technically this function may be called other ways too, but it
        # definitely cannot be called with --function.
        raise SaltCloudSystemExit(
            'The wait_for_instance action must be called with -a or --action.'
        )

    if vm_ is None:
        vm_ = {}

    if data is None:
        data = {}

    ssh_gateway_config = vm_.get(
        'gateway', get_ssh_gateway_config(vm_)
    )

    __utils__['cloud.fire_event'](
        'event',
        'waiting for ssh',
        'salt/cloud/{0}/waiting_for_ssh'.format(vm_['name']),
        args={'ip_address': ip_address},
        sock_dir=__opts__['sock_dir'],
        transport=__opts__['transport']
    )

    ssh_connect_timeout = config.get_cloud_config_value(
        'ssh_connect_timeout', vm_, __opts__, 900   # 15 minutes
    )
    ssh_port = config.get_cloud_config_value(
        'ssh_port', vm_, __opts__, 22
    )

    if config.get_cloud_config_value('win_installer', vm_, __opts__):
        username = config.get_cloud_config_value(
            'win_username', vm_, __opts__, default='Administrator'
        )
        win_passwd = config.get_cloud_config_value(
            'win_password', vm_, __opts__, default=''
        )
        win_deploy_auth_retries = config.get_cloud_config_value(
            'win_deploy_auth_retries', vm_, __opts__, default=10
        )
        win_deploy_auth_retry_delay = config.get_cloud_config_value(
            'win_deploy_auth_retry_delay', vm_, __opts__, default=1
        )
        use_winrm = config.get_cloud_config_value(
            'use_winrm', vm_, __opts__, default=False
        )
        winrm_verify_ssl = config.get_cloud_config_value(
            'winrm_verify_ssl', vm_, __opts__, default=True
        )

        if win_passwd and win_passwd == 'auto':
            log.debug('Waiting for auto-generated Windows EC2 password')
            while True:
                password_data = get_password_data(
                    name=vm_['name'],
                    kwargs={
                        'key_file': vm_['private_key'],
                    },
                    call='action',
                )
                win_passwd = password_data.get('password', None)
                if win_passwd is None:
                    log.debug(password_data)
                    # This wait is so high, because the password is unlikely to
                    # be generated for at least 4 minutes
                    time.sleep(60)
                else:
                    logging_data = password_data

                    logging_data['password'] = 'XXX-REDACTED-XXX'
                    logging_data['passwordData'] = 'XXX-REDACTED-XXX'
                    log.debug(logging_data)

                    vm_['win_password'] = win_passwd
                    break

        # SMB used whether psexec or winrm
        if not salt.utils.cloud.wait_for_port(ip_address,
                                              port=445,
                                              timeout=ssh_connect_timeout):
            raise SaltCloudSystemExit(
                'Failed to connect to remote windows host'
            )

        # If not using winrm keep same psexec behavior
        if not use_winrm:

            log.debug('Trying to authenticate via SMB using psexec')

            if not salt.utils.cloud.validate_windows_cred(ip_address,
                                                          username,
                                                          win_passwd,
                                                          retries=win_deploy_auth_retries,
                                                          retry_delay=win_deploy_auth_retry_delay):
                raise SaltCloudSystemExit(
                    'Failed to authenticate against remote windows host (smb)'
                )

        # If using winrm
        else:

            # Default HTTPS port can be changed in cloud configuration
            winrm_port = config.get_cloud_config_value(
                'winrm_port', vm_, __opts__, default=5986
            )

            # Wait for winrm port to be available
            if not salt.utils.cloud.wait_for_port(ip_address,
                                                  port=winrm_port,
                                                  timeout=ssh_connect_timeout):
                raise SaltCloudSystemExit(
                    'Failed to connect to remote windows host (winrm)'
                )

            log.debug('Trying to authenticate via Winrm using pywinrm')

            if not salt.utils.cloud.wait_for_winrm(ip_address,
                                                          winrm_port,
                                                          username,
                                                          win_passwd,
                                                          timeout=ssh_connect_timeout,
                                                          verify=winrm_verify_ssl):
                raise SaltCloudSystemExit(
                    'Failed to authenticate against remote windows host'
                )

    elif salt.utils.cloud.wait_for_port(ip_address,
                                        port=ssh_port,
                                        timeout=ssh_connect_timeout,
                                        gateway=ssh_gateway_config
                                        ):
        # If a known_hosts_file is configured, this instance will not be
        # accessible until it has a host key. Since this is provided on
        # supported instances by cloud-init, and viewable to us only from the
        # console output (which may take several minutes to become available,
        # we have some more waiting to do here.
        known_hosts_file = config.get_cloud_config_value(
            'known_hosts_file', vm_, __opts__, default=None
        )
        if known_hosts_file:
            console = {}
            while 'output_decoded' not in console:
                console = get_console_output(
                    instance_id=vm_['instance_id'],
                    call='action',
                    location=get_location(vm_)
                )
                pprint.pprint(console)
                time.sleep(5)
            output = salt.utils.stringutils.to_unicode(console['output_decoded'])
            comps = output.split('-----BEGIN SSH HOST KEY KEYS-----')
            if len(comps) < 2:
                # Fail; there are no host keys
                return False

            comps = comps[1].split('-----END SSH HOST KEY KEYS-----')
            keys = ''
            for line in comps[0].splitlines():
                if not line:
                    continue
                keys += '\n{0} {1}'.format(ip_address, line)

            with salt.utils.files.fopen(known_hosts_file, 'a') as fp_:
                fp_.write(salt.utils.stringutils.to_str(keys))
            fp_.close()

        for user in vm_['usernames']:
            if salt.utils.cloud.wait_for_passwd(
                host=ip_address,
                port=ssh_port,
                username=user,
                ssh_timeout=config.get_cloud_config_value(
                    'wait_for_passwd_timeout', vm_, __opts__, default=1 * 60
                ),
                key_filename=vm_['key_filename'],
                display_ssh_output=display_ssh_output,
                gateway=ssh_gateway_config,
                maxtries=config.get_cloud_config_value(
                    'wait_for_passwd_maxtries', vm_, __opts__, default=15
                ),
                known_hosts_file=config.get_cloud_config_value(
                    'known_hosts_file', vm_, __opts__,
                    default='/dev/null'
                ),
            ):
                __opts__['ssh_username'] = user
                vm_['ssh_username'] = user
                break
        else:
            raise SaltCloudSystemExit(
                'Failed to authenticate against remote ssh'
            )
    else:
        raise SaltCloudSystemExit(
            'Failed to connect to remote ssh'
        )

    if 'reactor' in vm_ and vm_['reactor'] is True:
        __utils__['cloud.fire_event'](
            'event',
            'ssh is available',
            'salt/cloud/{0}/ssh_ready_reactor'.format(vm_['name']),
            args={'ip_address': ip_address},
            sock_dir=__opts__['sock_dir'],
            transport=__opts__['transport']
        )

    return vm_