def get_password(vm_): ''' Return the password to use ''' return config.get_config_value( 'password', vm_, __opts__, default=config.get_config_value( 'passwd', vm_, __opts__, search_global=False ), search_global=False )
def get_conn(): ''' Return a conn object for the passed VM data ''' vm_ = get_configured_provider() driver = get_driver(Provider.IBM) return driver( config.get_config_value('user', vm_, __opts__, search_global=False), config.get_config_value('password', vm_, __opts__, search_global=False) )
def master_client(cloud): vm_ = cloud.vm_profile('master') provider = cloud.provider_profile_full(vm_) username = config.get_config_value('ssh_username', vm_, cloud.opts) hostname = cloud.opts['cloudseed'].get('ip_address', None) if 'private_key' in provider or 'private_key' in vm_: private_key = config.get_config_value('private_key', vm_, cloud.opts) return client(hostname=hostname, identity=private_key, username=username)
def get_password(vm_): ''' Return the password to use ''' return config.get_config_value('password', vm_, __opts__, default=config.get_config_value( 'passwd', vm_, __opts__, search_global=False), search_global=False)
def get_conn(): ''' Return a conn object for the passed VM data ''' driver = get_driver(Provider.GOGRID) vm_ = get_configured_provider() return driver( config.get_config_value( 'apikey', vm_, __opts__, search_global=False ), config.get_config_value( 'sharedsecret', vm_, __opts__, search_global=False ) )
def query(method='droplets', droplet_id=None, command=None, args=None): ''' Make a web call to Digital Ocean ''' path = 'https://api.digitalocean.com/{0}/'.format(method) if droplet_id: path = '{0}/'.format(droplet_id) if command: path += command if type(args) is not dict: args = {} args['client_id'] = config.get_config_value( 'client_key', get_configured_provider(), __opts__, search_global=False ) args['api_key'] = config.get_config_value( 'api_key', get_configured_provider(), __opts__, search_global=False ) path += '?%s' params = urllib.urlencode(args) request = urllib2.urlopen(path % params) if request.getcode() != 200: raise SaltCloudSystemExit( 'An error occurred while querying Digital Ocean. HTTP Code: {0} ' 'Error: {1!r}'.format( request.getcode(), request.read() ) ) log.debug(request.geturl()) content = request.read() request.close() result = json.loads(content) if result.get('status', '').lower() == 'error': raise SaltCloudSystemExit( ''.join( '{0}: {1}\n'.format(k, '\n'.join(v)) for (k, v) in result.get('error_message', {}).items() ) ) return result
def master_client(cloud): vm_ = cloud.vm_profile('master') provider = cloud.provider_profile_full(vm_) username = config.get_config_value('ssh_username', vm_, cloud.opts) hostname = cloud.opts['cloudseed'].get('ip_address', None) if 'private_key' in provider or 'private_key' in vm_: private_key = config.get_config_value('private_key', vm_, cloud.opts) return client( hostname=hostname, identity=private_key, username=username )
def _toggle_term_protect(name, enabled): ''' Toggle termination protection on a node ''' # region is required for all boto queries region = get_location(None) # init botocore vm_ = get_configured_provider() session = botocore.session.get_session() session.set_credentials( access_key=config.get_config_value( 'id', vm_, __opts__, search_global=False ), secret_key=config.get_config_value( 'key', vm_, __opts__, search_global=False ) ) service = session.get_service('ec2') endpoint = service.get_endpoint(region) # get the instance-id for the supplied node name conn = get_conn(location=region) node = get_node(conn, name) params = { 'instance_id': node.id, 'attribute': 'disableApiTermination', 'value': 'true' if enabled else 'false', } # get instance information operation = service.get_operation('modify-instance-attribute') http_response, response_data = operation.call(endpoint, **params) if http_response.status_code == 200: msg = 'Termination protection successfully {0} on {1}'.format( enabled and 'enabled' or 'disabled', name ) log.info(msg) return msg # No proper HTTP response!? msg = 'Bad response from AWS: {0}'.format(http_response.status_code) log.error(msg) return msg
def securitygroup(vm_): ''' Return the security group ''' return config.get_config_value( 'securitygroup', vm_, __opts__, search_global=False )
def keyname(vm_): ''' Return the keyname ''' return config.get_config_value( 'keyname', vm_, __opts__, search_global=False )
def get_availability_zone(vm_): ''' Return the availability zone to use ''' avz = config.get_config_value( 'availability_zone', vm_, __opts__, search_global=False ) if avz is None: return None zones = list_availability_zones() # Validate user-specified AZ if avz not in zones.keys(): raise SaltCloudException( 'The specified availability zone isn\'t valid in this region: ' '{0}\n'.format( avz ) ) # check specified AZ is available elif zones[avz] != 'available': raise SaltCloudException( 'The specified availability zone isn\'t currently available: ' '{0}\n'.format( avz ) ) return avz
def ssh_interface(vm_): ''' Return the ssh_interface type to connect to. Either 'public_ips' (default) or 'private_ips'. ''' return config.get_config_value( 'ssh_interface', vm_, __opts__, default='public_ips', search_global=False )
def get_conn(): ''' Return a conn object for the passed VM data ''' driver = get_driver(Provider.LINODE) return driver( config.get_config_value( 'apikey', get_configured_provider(), __opts__, search_global=False ) )
def get_location(conn, vm_): ''' Return the node location to use ''' locations = conn.list_locations() # Default to Dallas if not otherwise set loc = config.get_config_value('location', vm_, __opts__, default=2) for location in locations: if str(loc) in (str(location.id), str(location.name)): return location
def script(vm_): ''' Return the script deployment object ''' minion = saltcloud.utils.minion_conf_string(__opts__, vm_) script = saltcloud.utils.os_script( config.get_config_value('script', vm_, __opts__), vm_, __opts__, minion ) return script
def get_conn(): ''' Return a conn object for the passed VM data ''' driver = get_driver(Provider.HOSTVIRTUAL) return driver( config.get_config_value('apikey', get_configured_provider(), __opts__, search_global=False))
def bootstrap_minion(vm_): log.debug('Bootstrapping Minion %s', vm_) securitygroups = config.get_config_value('securitygroup', vm_, __opts__) marker = marker_security_group() create_securitygroup(name=vm_['name'], description='CloudseedApp') # merge security groups vm_['securitygroup'] = securitygroups + [vm_['name'], marker]
def get_size(vm_): ''' Return the VM's size. Used by create_node(). ''' sizes = avail_sizes() vm_size = str(config.get_config_value( 'size', vm_, __opts__, search_global=False )) for size in sizes: if vm_size in (sizes[size]['name'], sizes[size]['id']): return sizes[size]['id'] raise SaltCloudNotFound('The specified size could not be found.')
def get_image(vm_): ''' Return the image object to use ''' images = avail_images() vm_image = config.get_config_value( 'image', vm_, __opts__, search_global=False ) for image in images: if str(vm_image) in (images[image]['name'], images[image]['id']): return images[image]['id'] raise SaltCloudNotFound('The specified image could not be found.')
def get_location(conn, vm_): ''' Return the location object to use ''' locations = conn.list_locations() vm_location = config.get_config_value('location', vm_, __opts__) for img in locations: if vm_location and str(vm_location) in (str(img.id), str(img.name)): return img raise SaltCloudNotFound('The specified location could not be found.')
def action(*args, **kwargs): cloud = env.cloud() vm_ = cloud.vm_profile('master') ip_address = cloud.opts['cloudseed']['ip_address'] private_key = config.get_config_value('private_key', vm_, cloud.opts) username = config.get_config_value('ssh_username', vm_, cloud.opts) password = config.get_config_value('password', vm_, cloud.opts) socket = ssh.agent_zmq_tunnel(socket_type=zmq.REQ, host=ip_address, port='5556', private_key=private_key, username=username, password=password) socket.send_json(fun(*args, **kwargs)) response = socket.recv_json() if 'data' in response: return response['data']
def get_conn(): ''' Return a conn object for the passed VM data ''' vm_ = get_configured_provider() driver = get_driver(Provider.OPENSTACK) authinfo = { 'ex_force_auth_url': config.get_config_value( 'identity_url', vm_, __opts__, search_global=False ), 'ex_force_service_name': config.get_config_value( 'compute_name', vm_, __opts__, search_global=False ), 'ex_force_service_region': config.get_config_value( 'compute_region', vm_, __opts__, search_global=False ), 'ex_tenant_name': config.get_config_value( 'tenant', vm_, __opts__, search_global=False ), 'ex_force_service_name': config.get_config_value( 'compute_name', vm_, __opts__, search_global=False ) } password = config.get_config_value( 'password', vm_, __opts__, search_global=False ) if password is not None: authinfo['ex_force_auth_version'] = '2.0_password' log.debug('OpenStack authenticating using password') return driver( config.get_config_value( 'user', vm_, __opts__, search_global=False ), password, **authinfo ) authinfo['ex_force_auth_version'] = '2.0_apikey' log.debug('OpenStack authenticating using apikey') return driver( config.get_config_value('user', vm_, __opts__, search_global=False), config.get_config_value('apikey', vm_, __opts__, search_global=False), **authinfo )
def get_image(conn, vm_): ''' Return the image object to use ''' images = conn.list_images() vm_image = config.get_config_value('image', vm_, __opts__) for img in images: if vm_image and str(vm_image) in (str(img.id), str(img.name)): return img raise SaltCloudNotFound('The specified image could not be found.')
def action(*args, **kwargs): cloud = env.cloud() vm_ = cloud.vm_profile('master') ip_address = cloud.opts['cloudseed']['ip_address'] private_key = config.get_config_value('private_key', vm_, cloud.opts) username = config.get_config_value('ssh_username', vm_, cloud.opts) password = config.get_config_value('password', vm_, cloud.opts) socket = ssh.agent_zmq_tunnel( socket_type=zmq.REQ, host=ip_address, port='5556', private_key=private_key, username=username, password=password) socket.send_json(fun(*args, **kwargs)) response = socket.recv_json() if 'data' in response: return response['data']
def get_size(conn, vm_): ''' Return the VM's size object ''' sizes = conn.list_sizes() vm_size = config.get_config_value('size', vm_, __opts__) if not vm_size: return sizes[0] for size in sizes: if vm_size and str(vm_size) in (str(size.id), str(size.name)): return size raise SaltCloudNotFound('The specified size could not be found.')
def ssh_pub(vm_): ''' Deploy the primary ssh authentication key ''' ssh = config.get_config_value('ssh_auth', vm_, __opts__) if not ssh: return None ssh = os.path.expanduser(ssh) if os.path.isfile(ssh): return None return SSHKeyDeployment(open(ssh).read())
def get_location(vm_): ''' Return the VM's location ''' locations = avail_locations() vm_location = str(config.get_config_value( 'location', vm_, __opts__, search_global=False )) for location in locations: if vm_location in (locations[location]['name'], locations[location]['id']): return locations[location]['id'] raise SaltCloudNotFound('The specified location could not be found.')
def bootstrap_minion(vm_): log.debug('Bootstrapping Minion %s', vm_) securitygroups = config.get_config_value( 'securitygroup', vm_, __opts__) marker = marker_security_group() create_securitygroup( name=vm_['name'], description='CloudseedApp') # merge security groups vm_['securitygroup'] = securitygroups + [vm_['name'], marker]
def destroy(name, call=None): ''' Destroy a node. Will check termination protection and warn if enabled. CLI Example:: salt-cloud --destroy mymachine ''' instance_id = _get_node(name)['instanceId'] protected = show_term_protect( name=name, instance_id=instance_id, call='action', quiet=True ) if protected == 'true': raise SaltCloudSystemExit( 'This instance has been protected from being destroyed. ' 'Use the following command to disable protection:\n\n' 'salt-cloud -a disable_term_protect {0}'.format( name ) ) ret = {} if config.get_config_value('rename_on_destroy', get_configured_provider(), __opts__, search_global=False) is True: newname = '{0}-DEL{1}'.format(name, uuid.uuid4().hex) rename(name, kwargs={'newname': newname}, call='action') log.info( 'Machine will be identified as {0} until it has been ' 'cleaned up.'.format( newname ) ) ret['newname'] = newname params = {'Action': 'TerminateInstances', 'InstanceId.1': instance_id} result = query(params) log.info(result) ret.update(result[0]) return ret
def get_location(vm_=None): ''' Return the EC2 region to use, in this order: - CLI parameter - Cloud profile setting - Global salt-cloud config ''' return __opts__.get( 'location', config.get_config_value( 'location', vm_ or get_configured_provider(), __opts__, default=DEFAULT_LOCATION, #search_global=False ) )
def preferred_ip(vm_, ips): ''' Return the preferred Internet protocol. Either 'ipv4' (default) or 'ipv6'. ''' proto = config.get_config_value( 'protocol', vm_, __opts__, default='ipv4', search_global=False ) family = socket.AF_INET if proto == 'ipv6': family = socket.AF_INET6 for ip in ips: try: socket.inet_pton(family, ip) return ip except: continue return False
def ssh_username(vm_): ''' Return the ssh_username. Defaults to a built-in list of users for trying. ''' usernames = config.get_config_value( 'ssh_username', vm_, __opts__ ) if not isinstance(usernames, list): usernames = [usernames] # get rid of None's or empty names usernames = filter(lambda x: x, usernames) # Add common usernames to the list to be tested for name in ('ec2-user', 'ubuntu', 'admin', 'bitnami', 'root'): if name not in usernames: usernames.append(name) return usernames
def create(vm_): ''' Create a single VM from a data dict ''' log.info('Creating Cloud VM {0}'.format(vm_['name'])) saltcloud.utils.check_name(vm_['name'], 'a-zA-Z0-9._-') conn = get_conn() kwargs = { 'name': vm_['name'] } try: kwargs['image'] = get_image(conn, vm_) except Exception as exc: log.error( 'Error creating {0} on OPENSTACK\n\n' 'Could not find image {1}: {2}\n'.format( vm_['name'], vm_['image'], exc ), # Show the traceback if the debug logging level is enabled exc_info=log.isEnabledFor(logging.DEBUG) ) return False try: kwargs['size'] = get_size(conn, vm_) except Exception as exc: log.error( 'Error creating {0} on OPENSTACK\n\n' 'Could not find size {1}: {2}\n'.format( vm_['name'], vm_['size'], exc ), # Show the traceback if the debug logging level is enabled exc_info=log.isEnabledFor(logging.DEBUG) ) return False kwargs['ex_keyname'] = config.get_config_value( 'ssh_key_name', vm_, __opts__, search_global=False ) security_groups = config.get_config_value( 'security_groups', vm_, __opts__, search_global=False ) if security_groups is not None: vm_groups = security_groups.split(',') avail_groups = conn.ex_list_security_groups() group_list = [] for vg in vm_groups: if vg in [ag.name for ag in avail_groups]: group_list.append(vg) else: raise SaltCloudNotFound( 'No such security group: \'{0}\''.format( group ) ) kwargs['ex_security_groups'] = [ g for g in avail_groups if g.name in group_list ] try: data = conn.create_node(**kwargs) except Exception as exc: log.error( 'Error creating {0} on OPENSTACK\n\n' 'The following exception was thrown by libcloud when trying to ' 'run the initial deployment: {1}\n'.format( vm_['name'], exc ), # Show the traceback if the debug logging level is enabled exc_info=log.isEnabledFor(logging.DEBUG) ) return False not_ready = True nr_total = 50 nr_count = nr_total while not_ready: log.debug('Looking for IP addresses') nodelist = list_nodes(conn) private = nodelist[vm_['name']]['private_ips'] public = nodelist[vm_['name']]['public_ips'] running = nodelist[vm_['name']]['state'] == node_state( NodeState.RUNNING ) if running and private and not public: log.warn( 'Private IPs returned, but not public... Checking for ' 'misidentified IPs' ) for private_ip in private: private_ip = preferred_ip(vm_, [private_ip]) if saltcloud.utils.is_public_ip(private_ip): log.warn('{0} is a public ip'.format(private_ip)) data.public_ips.append(private_ip) not_ready = False else: log.warn('{0} is a private ip'.format(private_ip)) ignore_ip = ignore_ip_addr(vm_, private_ip) if private_ip not in data.private_ips and not ignore_ip: data.private_ips.append(private_ip) if ssh_interface(vm_) == 'private_ips' and data.private_ips: break if running and public: data.public_ips = public not_ready = False nr_count -= 1 if nr_count == 0: log.warn('Timed out waiting for a public ip, continuing anyway') break time.sleep(nr_total - nr_count + 5) if ssh_interface(vm_) == 'private_ips': ip_address = preferred_ip(vm_, data.private_ips) else: ip_address = preferred_ip(vm_, data.public_ips) log.debug('Using IP address {0}'.format(ip_address)) if not ip_address: raise SaltCloudException('A valid IP address was not found') deploy_kwargs = { 'host': ip_address, 'name': vm_['name'], 'sock_dir': __opts__['sock_dir'], 'start_action': __opts__['start_action'], 'minion_pem': vm_['priv_key'], 'minion_pub': vm_['pub_key'], 'keep_tmp': __opts__['keep_tmp'], 'script_args': config.get_config_value( 'script_args', vm_, __opts__ ) } deploy_kwargs['minion_conf'] = saltcloud.utils.minion_conf_string( __opts__, vm_ ) ssh_username = config.get_config_value( 'ssh_username', vm_, __opts__, default='root' ) if ssh_username != 'root': deploy_kwargs['deploy_command'] = '/tmp/deploy.sh' deploy_kwargs['username'] = ssh_username deploy_kwargs['tty'] = True log.debug('Using {0} as SSH username'.format(ssh_username)) ssh_key_file = config.get_config_value( 'ssh_key_file', vm_, __opts__, search_global=False ) if ssh_key_file is not None: deploy_kwargs['key_filename'] = ssh_key_file log.debug( 'Using {0} as SSH key file'.format(ssh_key_file) ) elif 'password' in data.extra: deploy_kwargs['password'] = data.extra['password'] log.debug('Logging into SSH using password') ret = {} sudo = config.get_config_value( 'sudo', vm_, __opts__, default=(ssh_username != 'root') ) if sudo is not None: deploy_kwargs['sudo'] = sudo log.debug('Running root commands using sudo') if config.get_config_value('deploy', vm_, __opts__) is True: deploy_script = script(vm_) deploy_kwargs['script'] = deploy_script.script # Deploy salt-master files, if necessary if config.get_config_value('make_master', vm_, __opts__) is True: deploy_kwargs['make_master'] = True deploy_kwargs['master_pub'] = vm_['master_pub'] deploy_kwargs['master_pem'] = vm_['master_pem'] master_conf = saltcloud.utils.master_conf_string(__opts__, vm_) if master_conf: deploy_kwargs['master_conf'] = master_conf if 'syndic_master' in master_conf: deploy_kwargs['make_syndic'] = True deployed = saltcloud.utils.deploy_script(**deploy_kwargs) if deployed: log.info('Salt installed on {0}'.format(vm_['name'])) if __opts__.get('show_deploy_args', False) is True: ret['deploy_kwargs'] = deploy_kwargs else: log.error( 'Failed to start Salt on Cloud VM {0}'.format( vm_['name'] ) ) log.info( 'Created Cloud VM {0} with the following values:'.format( vm_['name'] ) ) for key, val in data.__dict__.items(): ret[key] = val log.info(' {0}: {1}'.format(key, val)) return ret
def create(vm_): ''' Create a single VM from a data dict ''' log.info('Creating Cloud VM {0}'.format(vm_['name'])) conn = get_conn() kwargs = { 'name': vm_['name'], 'image': get_image(conn, vm_), 'size': get_size(conn, vm_), 'location': get_location(conn, vm_), 'auth': NodeAuthPassword(get_password(vm_)) } try: data = conn.create_node(**kwargs) except Exception as exc: log.error( 'Error creating {0} on LINODE\n\n' 'The following exception was thrown by libcloud when trying to ' 'run the initial deployment: \n{1}'.format( vm_['name'], exc.message ), # Show the traceback if the debug logging level is enabled exc_info=log.isEnabledFor(logging.DEBUG) ) return False ret = {} if config.get_config_value('deploy', vm_, __opts__) is True: deploy_script = script(vm_) deploy_kwargs = { 'host': data.public_ips[0], 'username': '******', 'password': get_password(vm_), 'script': deploy_script.script, 'name': vm_['name'], 'deploy_command': '/tmp/deploy.sh', 'start_action': __opts__['start_action'], 'sock_dir': __opts__['sock_dir'], 'conf_file': __opts__['conf_file'], 'minion_pem': vm_['priv_key'], 'minion_pub': vm_['pub_key'], 'keep_tmp': __opts__['keep_tmp'], 'script_args': config.get_config_value( 'script_args', vm_, __opts__ ) } deploy_kwargs['minion_conf'] = saltcloud.utils.minion_conf_string( __opts__, vm_ ) # Deploy salt-master files, if necessary if config.get_config_value('make_master', vm_, __opts__) is True: deploy_kwargs['make_master'] = True deploy_kwargs['master_pub'] = vm_['master_pub'] deploy_kwargs['master_pem'] = vm_['master_pem'] master_conf = saltcloud.utils.master_conf_string(__opts__, vm_) if master_conf: deploy_kwargs['master_conf'] = master_conf if 'syndic_master' in master_conf: deploy_kwargs['make_syndic'] = True deployed = saltcloud.utils.deploy_script(**deploy_kwargs) if deployed: log.info('Salt installed on {0}'.format(vm_['name'])) if __opts__.get('show_deploy_args', False) is True: ret['deploy_kwargs'] = deploy_kwargs else: log.error( 'Failed to start Salt on Cloud VM {0}'.format( vm_['name'] ) ) log.info( 'Created Cloud VM {0} with the following values:'.format( vm_['name'] ) ) for key, val in data.__dict__.items(): ret[key] = val log.info(' {0}: {1}'.format(key, val)) return ret
def create(vm_): ''' Provision a single machine ''' if config.get_config_value('deploy', vm_, __opts__) is False: return { 'Error': { 'No Deploy': '\'deploy\' is not enabled. Not deploying.' } } ret = {} log.info('Provisioning existing machine {0}'.format(vm_['name'])) ssh_username = config.get_config_value('ssh_username', vm_, __opts__) deploy_script = script(vm_) deploy_kwargs = { 'host': vm_['ssh_host'], 'username': ssh_username, 'script': deploy_script, 'name': vm_['name'], 'deploy_command': '/tmp/deploy.sh', 'start_action': __opts__['start_action'], 'sock_dir': __opts__['sock_dir'], 'conf_file': __opts__['conf_file'], 'minion_pem': vm_['priv_key'], 'minion_pub': vm_['pub_key'], 'keep_tmp': __opts__['keep_tmp'], 'sudo': config.get_config_value( 'sudo', vm_, __opts__, default=(ssh_username != 'root') ), 'password': config.get_config_value( 'password', vm_, __opts__, search_global=False ), 'ssh_keyfile': config.get_config_value( 'ssh_keyfile', vm_, __opts__, search_global=False ), 'script_args': config.get_config_value( 'script_args', vm_, __opts__ ), 'minion_conf': saltcloud.utils.minion_conf_string(__opts__, vm_) } # Deploy salt-master files, if necessary if config.get_config_value('make_master', vm_, __opts__) is True: deploy_kwargs['make_master'] = True deploy_kwargs['master_pub'] = vm_['master_pub'] deploy_kwargs['master_pem'] = vm_['master_pem'] master_conf = saltcloud.utils.master_conf_string(__opts__, vm_) if master_conf: deploy_kwargs['master_conf'] = master_conf if 'syndic_master' in master_conf: deploy_kwargs['make_syndic'] = True deployed = saltcloud.utils.deploy_script(**deploy_kwargs) if deployed: ret['deployed'] = deployed log.info('Salt installed on {0}'.format(vm_['name'])) if __opts__.get('show_deploy_args', False) is True: ret['deploy_kwargs'] = deploy_kwargs return ret log.error('Failed to start Salt on host {0}'.format(vm_['name'])) return { 'Error': { 'Not Deployed': 'Failed to start Salt on host {0}'.format( vm_['name'] ) } }
def create(vm_): ''' Create a single VM from a data dict ''' saltcloud.utils.fire_event( 'event', 'starting create', 'salt/cloud/{0}/creating'.format(vm_['name']), { 'name': vm_['name'], 'profile': vm_['profile'], 'provider': vm_['provider'], }, ) log.info('Creating Cloud VM {0}'.format(vm_['name'])) conn = get_conn() kwargs = { 'name': vm_['name'], 'image': get_image(conn, vm_), 'size': get_size(conn, vm_), 'location': get_location(conn, vm_), 'auth': NodeAuthPassword(get_password(vm_)) } saltcloud.utils.fire_event( 'event', 'requesting instance', 'salt/cloud/{0}/requesting'.format(vm_['name']), { 'kwargs': { 'name': kwargs['name'], 'image': kwargs['image'].name, 'size': kwargs['size'].name, 'location': kwargs['location'].name } }, ) try: # pop off the first 3 since f*****g hv driver # doesn't use kwargs for these 3... # whereas auth and location are... name = kwargs.pop('name') image = kwargs.pop('image') size = kwargs.pop('size') data = conn.create_node(name, image, size, **kwargs) except Exception as exc: log.error( 'Error creating {0} on HOSTVIRTUAL\n\n' 'The following exception was thrown by libcloud when trying to ' 'run the initial deployment: \n{1}'.format(vm_['name'], exc.message), # Show the traceback if the debug logging level is enabled exc_info=log.isEnabledFor(logging.DEBUG)) return False ssh_username = config.get_config_value('ssh_username', vm_, __opts__, default='root') ret = {} if config.get_config_value('deploy', vm_, __opts__) is True: deploy_script = script(vm_) deploy_kwargs = { 'host': data.public_ips[0], 'username': ssh_username, 'password': get_password(vm_), 'script': deploy_script.script, 'name': vm_['name'], 'tmp_dir': config.get_config_value('tmp_dir', vm_, __opts__, default='/tmp/.saltcloud'), 'deploy_command': config.get_config_value( 'deploy_command', vm_, __opts__, default='/tmp/.saltcloud/deploy.sh', ), 'start_action': __opts__['start_action'], 'parallel': __opts__['parallel'], 'sock_dir': __opts__['sock_dir'], 'conf_file': __opts__['conf_file'], 'minion_pem': vm_['priv_key'], 'minion_pub': vm_['pub_key'], 'keep_tmp': __opts__['keep_tmp'], 'preseed_minion_keys': vm_.get('preseed_minion_keys', None), 'sudo': config.get_config_value('sudo', vm_, __opts__, default=(ssh_username != 'root')), 'sudo_password': config.get_config_value('sudo_password', vm_, __opts__, default=None), 'tty': config.get_config_value('tty', vm_, __opts__, default=False), 'display_ssh_output': config.get_config_value('display_ssh_output', vm_, __opts__, default=True), 'script_args': config.get_config_value('script_args', vm_, __opts__), 'script_env': config.get_config_value('script_env', vm_, __opts__), 'minion_conf': saltcloud.utils.minion_config(__opts__, vm_) } # Deploy salt-master files, if necessary if config.get_config_value('make_master', vm_, __opts__) is True: deploy_kwargs['make_master'] = True deploy_kwargs['master_pub'] = vm_['master_pub'] deploy_kwargs['master_pem'] = vm_['master_pem'] master_conf = saltcloud.utils.master_config(__opts__, vm_) deploy_kwargs['master_conf'] = master_conf if master_conf.get('syndic_master', None): deploy_kwargs['make_syndic'] = True deploy_kwargs['make_minion'] = config.get_config_value('make_minion', vm_, __opts__, default=True) # Store what was used to the deploy the VM event_kwargs = copy.deepcopy(deploy_kwargs) del (event_kwargs['minion_pem']) del (event_kwargs['minion_pub']) del (event_kwargs['sudo_password']) if 'password' in event_kwargs: del (event_kwargs['password']) ret['deploy_kwargs'] = event_kwargs saltcloud.utils.fire_event( 'event', 'executing deploy script', 'salt/cloud/{0}/deploying'.format(vm_['name']), {'kwargs': event_kwargs}, ) deployed = False deployed = saltcloud.utils.deploy_script(**deploy_kwargs) if deployed: log.info('Salt installed on {0}'.format(vm_['name'])) else: log.error('Failed to start Salt on Cloud VM {0}'.format( vm_['name'])) log.info('Created Cloud VM {0[name]!r}'.format(vm_)) log.debug('{0[name]!r} VM creation details:\n{1}'.format( vm_, pprint.pformat(data.__dict__))) ret.update(data.__dict__) saltcloud.utils.fire_event( 'event', 'created instance', 'salt/cloud/{0}/created'.format(vm_['name']), { 'name': vm_['name'], 'profile': vm_['profile'], 'provider': vm_['provider'], }, ) return ret
def run(argv): args = docopt(__doc__, argv=argv) # TODO We can capture all this loading and error handling # in 1 function try: with open('cloudseed/current/salt/cloud.profiles') as f: profiles = yaml.load(f.read()) except IOError: print('No Cloud Profiles Found') return try: with open('cloudseed/current/salt/cloud.providers') as f: providers = yaml.load(f.read()) except IOError: print('No Cloud Providers Found') return try: with open('cloudseed/current/salt/cloudseed') as f: conf = yaml.load(f.read()) except IOError: print('Have you bootstrapped?') return profile = profiles.get('master', None) if not profile: # TODO Add Error Messaging return prefix = os.path.join(env.current_env_path(), 'salt') cloud_config = os.path.join(prefix, 'cloud') cloud_providers = os.path.join(prefix, 'cloud.providers') cloud_profiles = os.path.join(prefix, 'cloud.profiles') master_config = os.path.join(prefix, 'master') cloudseed_args = [ '--cloud-config', cloud_config, '--providers-config', cloud_providers, '--profiles', cloud_profiles, '--master-config', master_config ] cli = saltcloud.cli.SaltCloud() cli.parse_args(args=cloudseed_args) cloud = cloudseed.cloud.Cloud(cli.config) vm_ = cloud.vm_profile('master') provider = config.get_config_value('provider', vm_, cloud.opts) if not provider: # TODO Add Error Messaging return username = config.get_config_value('ssh_username', vm_, cloud.opts) identity = config.get_config_value('private_key', vm_, cloud.opts) host = conf.get('ip_address', False) if username and identity and host: identity = os.path.abspath(identity) #sys.stdout.write('Connecting to environment \'%s\'\n' % current_env) ssh.connect(host=host, username=username, identity=identity)