mirror of
https://github.com/valitydev/salt.git
synced 2024-11-08 17:33:54 +00:00
Break out ec2 create() into smaller functions
This commit is contained in:
parent
03cc44cde4
commit
f0b1a01126
@ -1055,49 +1055,21 @@ def _param_from_config(key, data):
|
||||
return param
|
||||
|
||||
|
||||
def create(vm_=None, call=None):
|
||||
def request_instance(vm_=None, call=None):
|
||||
'''
|
||||
Create a single VM from a data dict
|
||||
Put together all of the information necessary to request an instance on EC2,
|
||||
and then fire off the request the instance.
|
||||
|
||||
Returns data about the instance
|
||||
'''
|
||||
if call:
|
||||
if call == 'function':
|
||||
# Technically this function may be called other ways too, but it
|
||||
# definitely cannot be called with --function.
|
||||
raise SaltCloudSystemExit(
|
||||
'You cannot create an instance with -a or -f.'
|
||||
'The request_instance action must be called with -a or --action.'
|
||||
)
|
||||
|
||||
salt.utils.cloud.fire_event(
|
||||
'event',
|
||||
'starting create',
|
||||
'salt/cloud/{0}/creating'.format(vm_['name']),
|
||||
{
|
||||
'name': vm_['name'],
|
||||
'profile': vm_['profile'],
|
||||
'provider': vm_['provider'],
|
||||
},
|
||||
transport=__opts__['transport']
|
||||
)
|
||||
|
||||
key_filename = config.get_cloud_config_value(
|
||||
'private_key', vm_, __opts__, search_global=False, default=None
|
||||
)
|
||||
if key_filename is not None and not os.path.isfile(key_filename):
|
||||
raise SaltCloudConfigError(
|
||||
'The defined key_filename {0!r} does not exist'.format(
|
||||
key_filename
|
||||
)
|
||||
)
|
||||
|
||||
# Get SSH Gateway config early to verify the private_key,
|
||||
# if used, exists or not. We don't want to deploy an instance
|
||||
# and not be able to access it via the gateway.
|
||||
ssh_gateway_config = get_ssh_gateway_config(vm_)
|
||||
|
||||
location = get_location(vm_)
|
||||
log.info('Creating Cloud VM {0} in {1}'.format(vm_['name'], location))
|
||||
usernames = salt.utils.cloud.ssh_usernames(
|
||||
vm_,
|
||||
__opts__,
|
||||
default_users=('ec2-user', 'ubuntu', 'admin', 'bitnami', 'root')
|
||||
)
|
||||
location = vm_.get('location', get_location(vm_))
|
||||
|
||||
# do we launch a regular vm or a spot instance?
|
||||
# see http://goo.gl/hYZ13f for more information on EC2 API
|
||||
@ -1309,25 +1281,6 @@ def create(vm_=None, call=None):
|
||||
'\'del_all_vols_on_destroy\' should be a boolean value.'
|
||||
)
|
||||
|
||||
tags = config.get_cloud_config_value('tag',
|
||||
vm_,
|
||||
__opts__,
|
||||
{},
|
||||
search_global=False)
|
||||
if not isinstance(tags, dict):
|
||||
raise SaltCloudConfigError(
|
||||
'\'tag\' should be a dict.'
|
||||
)
|
||||
|
||||
for value in tags.values():
|
||||
if not isinstance(value, str):
|
||||
raise SaltCloudConfigError(
|
||||
'\'tag\' values must be strings. Try quoting the values. '
|
||||
'e.g. "2013-09-19T20:09:46Z".'
|
||||
)
|
||||
|
||||
tags['Name'] = vm_['name']
|
||||
|
||||
salt.utils.cloud.fire_event(
|
||||
'event',
|
||||
'requesting instance',
|
||||
@ -1439,9 +1392,22 @@ def create(vm_=None, call=None):
|
||||
finally:
|
||||
raise SaltCloudSystemExit(exc.message)
|
||||
|
||||
# Pull the instance ID, valid for both spot and normal instances
|
||||
instance_id = data[0]['instanceId']
|
||||
return data
|
||||
|
||||
|
||||
def query_instance(vm_=None, call=None):
|
||||
'''
|
||||
Query an instance upon creation from the EC2 API
|
||||
'''
|
||||
if call == 'function':
|
||||
# Technically this function may be called other ways too, but it
|
||||
# definitely cannot be called with --function.
|
||||
raise SaltCloudSystemExit(
|
||||
'The query_instance action must be called with -a or --action.'
|
||||
)
|
||||
|
||||
instance_id = vm_['instance_id']
|
||||
location = vm_.get('location', get_location(vm_))
|
||||
salt.utils.cloud.fire_event(
|
||||
'event',
|
||||
'querying instance',
|
||||
@ -1530,29 +1496,34 @@ def create(vm_=None, call=None):
|
||||
finally:
|
||||
raise SaltCloudSystemExit(exc.message)
|
||||
|
||||
salt.utils.cloud.fire_event(
|
||||
'event',
|
||||
'setting tags',
|
||||
'salt/cloud/{0}/tagging'.format(vm_['name']),
|
||||
{'tags': tags},
|
||||
transport=__opts__['transport']
|
||||
)
|
||||
return data
|
||||
|
||||
set_tags(
|
||||
vm_['name'], tags,
|
||||
instance_id=instance_id, call='action', location=location
|
||||
)
|
||||
log.info('Created node {0}'.format(vm_['name']))
|
||||
|
||||
if ssh_interface(vm_) == 'private_ips':
|
||||
ip_address = data[0]['instancesSet']['item']['privateIpAddress']
|
||||
log.info('Salt node data. Private_ip: {0}'.format(ip_address))
|
||||
else:
|
||||
ip_address = data[0]['instancesSet']['item']['ipAddress']
|
||||
log.info('Salt node data. Public_ip: {0}'.format(ip_address))
|
||||
def wait_for_instance(
|
||||
vm_=None,
|
||||
data=None,
|
||||
ip_address=None,
|
||||
display_ssh_output=True,
|
||||
call=None,
|
||||
):
|
||||
'''
|
||||
Wait for an instance upon creation from the EC2 API, to become available
|
||||
'''
|
||||
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.'
|
||||
)
|
||||
|
||||
display_ssh_output = config.get_cloud_config_value(
|
||||
'display_ssh_output', vm_, __opts__, default=True
|
||||
if vm_ is None:
|
||||
vm_ = {}
|
||||
|
||||
if data is None:
|
||||
data = {}
|
||||
|
||||
ssh_gateway_config = vm_.get(
|
||||
'ssh_gateway_config', get_ssh_gateway_config(vm_)
|
||||
)
|
||||
|
||||
salt.utils.cloud.fire_event(
|
||||
@ -1590,13 +1561,13 @@ def create(vm_=None, call=None):
|
||||
timeout=ssh_connect_timeout,
|
||||
gateway=ssh_gateway_config
|
||||
):
|
||||
for user in usernames:
|
||||
for user in vm_['usernames']:
|
||||
if salt.utils.cloud.wait_for_passwd(
|
||||
host=ip_address,
|
||||
username=user,
|
||||
ssh_timeout=config.get_cloud_config_value(
|
||||
'wait_for_passwd_timeout', vm_, __opts__, default=1 * 60),
|
||||
key_filename=key_filename,
|
||||
key_filename=vm_['key_filename'],
|
||||
display_ssh_output=display_ssh_output,
|
||||
gateway=ssh_gateway_config
|
||||
):
|
||||
@ -1613,119 +1584,135 @@ def create(vm_=None, call=None):
|
||||
'Failed to connect to remote ssh'
|
||||
)
|
||||
|
||||
ret = {}
|
||||
|
||||
ssh_username = config.get_cloud_config_value(
|
||||
'ssh_username', vm_, __opts__
|
||||
)
|
||||
|
||||
if config.get_cloud_config_value('deploy', vm_, __opts__) is True:
|
||||
deploy_script = script(vm_)
|
||||
deploy_kwargs = {
|
||||
'opts': __opts__,
|
||||
'host': ip_address,
|
||||
'username': ssh_username,
|
||||
'key_filename': key_filename,
|
||||
'tmp_dir': config.get_cloud_config_value(
|
||||
'tmp_dir', vm_, __opts__, default='/tmp/.saltcloud'
|
||||
),
|
||||
'deploy_command': config.get_cloud_config_value(
|
||||
'deploy_command', vm_, __opts__,
|
||||
default='/tmp/.saltcloud/deploy.sh',
|
||||
),
|
||||
'tty': config.get_cloud_config_value(
|
||||
'tty', vm_, __opts__, default=True
|
||||
),
|
||||
'script': deploy_script,
|
||||
'name': vm_['name'],
|
||||
'sudo': config.get_cloud_config_value(
|
||||
'sudo', vm_, __opts__, default=(ssh_username != 'root')
|
||||
),
|
||||
'sudo_password': config.get_cloud_config_value(
|
||||
'sudo_password', vm_, __opts__, default=None
|
||||
),
|
||||
'start_action': __opts__['start_action'],
|
||||
'parallel': __opts__['parallel'],
|
||||
'conf_file': __opts__['conf_file'],
|
||||
'sock_dir': __opts__['sock_dir'],
|
||||
'minion_pem': vm_['priv_key'],
|
||||
'minion_pub': vm_['pub_key'],
|
||||
'keep_tmp': __opts__['keep_tmp'],
|
||||
'preseed_minion_keys': vm_.get('preseed_minion_keys', None),
|
||||
'display_ssh_output': display_ssh_output,
|
||||
'minion_conf': salt.utils.cloud.minion_config(__opts__, vm_),
|
||||
'script_args': config.get_cloud_config_value(
|
||||
'script_args', vm_, __opts__
|
||||
),
|
||||
'script_env': config.get_cloud_config_value(
|
||||
'script_env', vm_, __opts__
|
||||
)
|
||||
}
|
||||
|
||||
# Deploy salt-master files, if necessary
|
||||
if config.get_cloud_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 = salt.utils.cloud.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_cloud_config_value(
|
||||
'make_minion', vm_, __opts__, default=True
|
||||
)
|
||||
|
||||
# Check for Windows install params
|
||||
win_installer = config.get_cloud_config_value('win_installer',
|
||||
vm_,
|
||||
__opts__)
|
||||
if win_installer:
|
||||
deploy_kwargs['win_installer'] = win_installer
|
||||
minion = salt.utils.cloud.minion_config(__opts__, vm_)
|
||||
deploy_kwargs['master'] = minion['master']
|
||||
deploy_kwargs['username'] = config.get_cloud_config_value(
|
||||
'win_username', vm_, __opts__, default='Administrator'
|
||||
)
|
||||
deploy_kwargs['password'] = config.get_cloud_config_value(
|
||||
'win_password', vm_, __opts__, default=''
|
||||
)
|
||||
|
||||
# Copy ssh_gateway_config into deploy scripts
|
||||
if ssh_gateway_config:
|
||||
deploy_kwargs['gateway'] = ssh_gateway_config
|
||||
|
||||
# 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']
|
||||
if 'gateway' in event_kwargs:
|
||||
if 'ssh_gateway_password' in event_kwargs['gateway']:
|
||||
del event_kwargs['gateway']['ssh_gateway_password']
|
||||
ret['deploy_kwargs'] = event_kwargs
|
||||
|
||||
if 'reactor' in vm_ and vm_['reactor'] is True:
|
||||
salt.utils.cloud.fire_event(
|
||||
'event',
|
||||
'executing deploy script',
|
||||
'salt/cloud/{0}/deploying'.format(vm_['name']),
|
||||
{'kwargs': event_kwargs},
|
||||
'ssh is available',
|
||||
'salt/cloud/{0}/ssh_ready_reactor'.format(vm_['name']),
|
||||
{'ip_address': ip_address},
|
||||
transport=__opts__['transport']
|
||||
)
|
||||
|
||||
deployed = False
|
||||
if win_installer:
|
||||
deployed = salt.utils.cloud.deploy_windows(**deploy_kwargs)
|
||||
else:
|
||||
deployed = salt.utils.cloud.deploy_script(**deploy_kwargs)
|
||||
|
||||
if deployed:
|
||||
log.info('Salt installed on {name}'.format(**vm_))
|
||||
else:
|
||||
log.error('Failed to start Salt on Cloud VM {name}'.format(**vm_))
|
||||
def create(vm_=None, call=None):
|
||||
'''
|
||||
Create a single VM from a data dict
|
||||
'''
|
||||
if call:
|
||||
raise SaltCloudSystemExit(
|
||||
'You cannot create an instance with -a or -f.'
|
||||
)
|
||||
|
||||
salt.utils.cloud.fire_event(
|
||||
'event',
|
||||
'starting create',
|
||||
'salt/cloud/{0}/creating'.format(vm_['name']),
|
||||
{
|
||||
'name': vm_['name'],
|
||||
'profile': vm_['profile'],
|
||||
'provider': vm_['provider'],
|
||||
},
|
||||
transport=__opts__['transport']
|
||||
)
|
||||
|
||||
key_filename = config.get_cloud_config_value(
|
||||
'private_key', vm_, __opts__, search_global=False, default=None
|
||||
)
|
||||
if key_filename is not None and not os.path.isfile(key_filename):
|
||||
raise SaltCloudConfigError(
|
||||
'The defined key_filename {0!r} does not exist'.format(
|
||||
key_filename
|
||||
)
|
||||
)
|
||||
vm_['key_filename'] = key_filename
|
||||
|
||||
# Get SSH Gateway config early to verify the private_key,
|
||||
# if used, exists or not. We don't want to deploy an instance
|
||||
# and not be able to access it via the gateway.
|
||||
ssh_gateway_config = get_ssh_gateway_config(vm_)
|
||||
vm_['ssh_gateway_config'] = ssh_gateway_config
|
||||
|
||||
location = get_location(vm_)
|
||||
vm_['location'] = location
|
||||
|
||||
log.info('Creating Cloud VM {0} in {1}'.format(vm_['name'], location))
|
||||
vm_['usernames'] = salt.utils.cloud.ssh_usernames(
|
||||
vm_,
|
||||
__opts__,
|
||||
default_users=(
|
||||
'ec2-user', 'ubuntu', 'fedora', 'admin', 'bitnami', 'root'
|
||||
)
|
||||
)
|
||||
|
||||
# Put together all of the information required to request the instance, and
|
||||
# then fire off the request for it
|
||||
data = request_instance(vm_, location)
|
||||
|
||||
# Pull the instance ID, valid for both spot and normal instances
|
||||
instance_id = data[0]['instanceId']
|
||||
vm_['instance_id'] = instance_id
|
||||
|
||||
# Wait for vital information, such as IP addresses, to be available
|
||||
# for the new instance
|
||||
data = query_instance(vm_)
|
||||
|
||||
# Now that the instance is available, tag it appropriately. Should
|
||||
# mitigate race conditions with tags
|
||||
tags = config.get_cloud_config_value('tag',
|
||||
vm_,
|
||||
__opts__,
|
||||
{},
|
||||
search_global=False)
|
||||
if not isinstance(tags, dict):
|
||||
raise SaltCloudConfigError(
|
||||
'\'tag\' should be a dict.'
|
||||
)
|
||||
|
||||
for value in tags.values():
|
||||
if not isinstance(value, str):
|
||||
raise SaltCloudConfigError(
|
||||
'\'tag\' values must be strings. Try quoting the values. '
|
||||
'e.g. "2013-09-19T20:09:46Z".'
|
||||
)
|
||||
|
||||
tags['Name'] = vm_['name']
|
||||
|
||||
salt.utils.cloud.fire_event(
|
||||
'event',
|
||||
'setting tags',
|
||||
'salt/cloud/{0}/tagging'.format(vm_['name']),
|
||||
{'tags': tags},
|
||||
transport=__opts__['transport']
|
||||
)
|
||||
|
||||
set_tags(
|
||||
vm_['name'], tags,
|
||||
instance_id=instance_id, call='action', location=location
|
||||
)
|
||||
|
||||
# At this point, the node is created and tagged, and now needs to be
|
||||
# bootstrapped, once the necessary port is available.
|
||||
log.info('Created node {0}'.format(vm_['name']))
|
||||
|
||||
# Wait for the necessary port to become available to bootstrap
|
||||
if ssh_interface(vm_) == 'private_ips':
|
||||
ip_address = data[0]['instancesSet']['item']['privateIpAddress']
|
||||
log.info('Salt node data. Private_ip: {0}'.format(ip_address))
|
||||
else:
|
||||
ip_address = data[0]['instancesSet']['item']['ipAddress']
|
||||
log.info('Salt node data. Public_ip: {0}'.format(ip_address))
|
||||
vm_['ssh_host'] = ip_address
|
||||
|
||||
display_ssh_output = config.get_cloud_config_value(
|
||||
'display_ssh_output', vm_, __opts__, default=True
|
||||
)
|
||||
|
||||
wait_for_instance(
|
||||
vm_, data, ip_address, display_ssh_output
|
||||
)
|
||||
|
||||
# The instance is booted and accessable, let's Salt it!
|
||||
ret = salt.utils.cloud.bootstrap(vm_, __opts__)
|
||||
|
||||
log.info('Created Cloud VM {0[name]!r}'.format(vm_))
|
||||
log.debug(
|
||||
|
@ -293,10 +293,10 @@ def bootstrap(vm_, opts):
|
||||
|
||||
ret = {}
|
||||
|
||||
deploy_script_code = os_script(vm_)
|
||||
deploy_script_code = os_script('script', vm_, opts)
|
||||
|
||||
ssh_username = salt.config.get_cloud_config_value(
|
||||
'ssh_username', vm_, __opts__, default='root'
|
||||
'ssh_username', vm_, opts, default='root'
|
||||
),
|
||||
|
||||
deploy_kwargs = {
|
||||
|
Loading…
Reference in New Issue
Block a user