def deploy(target, output=True, ret=None, hooks=True, pre=True, post=True): '''Prepare cloud controller configuration can also apply per virtualization type configuration''' __salt__['mc_cloud_compute_node.lazy_register_configuration'](target) func_name = 'mc_compute_node.deploy {0}'.format(target) __salt__['mc_api.time_log']('start {0}'.format(func_name)) if ret is None: ret = result() ret['comment'] += green('Installing compute node configuration\n') if hooks and pre: run_vt_hook('pre_deploy_compute_node', ret=ret, target=target, output=output) for step in [ register_configuration, configure_prevt, # merged in configure_prevt for perf reason # configure_sshkeys, # configure_grains, install_vts, configure_network, configure_host, # merged in configure_host for perf reason # configure_hostsfile, # configure_firewall, # configure_sslcerts, # configure_reverse_proxy ]: step(target, ret=ret, output=False) check_point(ret, __opts__, output=output) if hooks and post: run_vt_hook('post_deploy_compute_node', ret=ret, target=target, output=output) salt_output(ret, __opts__, output=output) __salt__['mc_api.time_log']('end {0}'.format(func_name)) return ret
def step(vm, step, compute_node=None, vt=None, ret=None, output=True): '''Execute a step on a VM noder''' func_name = 'mc_cloud_vm.provision.step {0} {1}'.format(vm, step) __salt__['mc_api.time_log']('start {0}'.format(func_name)) compute_node = __salt__['mc_cloud_vm.get_compute_node'](vm, compute_node) vt = __salt__['mc_cloud_vm.get_vt'](vm, vt) if ret is None: ret = result() pre_vid_ = 'mc_cloud_{0}.vm_{1}'.format(vt, step) id_ = 'mc_cloud_vm.vm_{1}'.format(vt, step) post_vid_ = 'mc_cloud_{0}.post_vm_{1}'.format(vt, step) for cid_ in [pre_vid_, id_, post_vid_]: if (not ret['result']) or (cid_ not in __salt__): continue try: ret = __salt__[cid_](vm, compute_node=compute_node, vt=vt, ret=ret, output=False) check_point(ret, __opts__, output=output) except FailedStepError: ret['result'] = False except Exception, exc: trace = traceback.format_exc() ret['trace'] += 'lxcprovision: {0} in {1}\n'.format( exc, cid_) ret['trace'] += trace ret['result'] = False ret['comment'] += red('unmanaged exception for ' '{0}/{1}/{2}'.format(compute_node, vt, vm)) if ret['result']: ret['trace'] = '' ret['output'] = ''
def register_configurations(compute_node, skip=None, only=None, ret=None, output=True, refresh=False): '''Register all configurations in localregistries for reachable vms :: mastersalt-run -lall mc_cloud_vm.register_configurations host1.domain.tld mastersalt-run -lall mc_cloud_vm.register_configurations host1.domain.tld only=['foo.domain.tld'] mastersalt-run -lall mc_cloud_vm.register_configurations host1.domain.tld skip=['foo2.domain.tld'] ''' func_name = 'mc_cloud_vm.configuration_vms' __salt__['mc_api.time_log']('start {0}'.format(func_name)) if ret is None: ret = result() _, only, __, skip = ( __salt__['mc_cloud_controller.gather_only_skip']( only_vms=only, skip_vms=skip)) if refresh: cli('saltutil.refresh_pillar') settings = cli('mc_cloud_compute_node.settings') gprov = ret['changes'].setdefault('vms_configured', {}) gerror = ret['changes'].setdefault('vms_in_error', {}) configured = gprov.setdefault(compute_node, []) configuration_error = gerror.setdefault(compute_node, []) vms = settings['targets'].get(compute_node, {'virt_types': [], 'vms': {}}) vms = filter_vms(compute_node, vms['vms'], skip, only) kvms = [a for a in vms] kvms.sort() for idx, vm in enumerate(kvms): vt = vms[vm] cret = result() try: # first: register the conf on compute node if not cli('test.ping', salt_target=compute_node): raise FailedStepError('not reachable') cret = register_configuration_on_cn(vm, compute_node=compute_node, vt=vt, ret=cret, output=False) check_point(cret, __opts__, output=output) # second: register the conf on VM # this may fail if the vm is not yet spawned if not cli('test.ping', salt_target=vm): raise FailedStepError('not reachable') cret = register_configuration(vm, compute_node=compute_node, vt=vt, ret=cret, output=False) check_point(cret, __opts__, output=output) except FailedStepError, exc: trace = traceback.format_exc() cret['trace'] += '{0}\n'.format(exc.message) cret['result'] = False except Exception, exc: trace = traceback.format_exc() cret = {'result': False, 'output': 'unknown error on {0}/{2}\n{1}'.format( compute_node, exc, vm), 'comment': 'unknown error on {0}/{1}\n'.format( compute_node, vm), 'trace': trace}
def register_configurations(only=None, only_vms=None, skip=None, skip_vms=None, refresh=False, ret=None, output=True): '''Parse all reachable compute nodes and vms and regenerate the local configuration registries concerning cloud deployment''' func_name = 'mc_compute_node.register_configurations' __salt__['mc_api.time_log']('start {0}'.format(func_name)) only, _, skip, __ = ( __salt__['mc_cloud_controller.gather_only_skip']( only=only, skip=skip)) if ret is None: ret = result() if refresh: cli('saltutil.refresh_pillar') settings = cli('mc_cloud_compute_node.settings') configuration = ret['changes'].setdefault('cns_configured', []) configuration_error = ret['changes'].setdefault('cns_in_error', []) targets = [a for a in settings['targets']] # targets += ['foo', 'bar'] targets = filter_compute_nodes(targets, skip, only) hosts_to_configure_vms = [] for idx, compute_node in enumerate(targets): cret = result() try: if not cli('test.ping', salt_target=compute_node): raise FailedStepError('not reachable') register_configuration(compute_node, ret=cret, output=False) check_point(cret, __opts__, output=output) if compute_node not in hosts_to_configure_vms: hosts_to_configure_vms.append(compute_node) except FailedStepError: cret['result'] = False except Exception, exc: trace = traceback.format_exc() cret = {'result': False, 'output': 'unknown error on {0}\n{1}'.format(compute_node, exc), 'comment': 'unknown error on {0}\n'.format(compute_node), 'trace': trace} if cret['result']: if compute_node not in configuration: configuration.append(compute_node) # if everything is well, wipe the unseful output cret['output'] = '' cret['trace'] = '' else: ret['result'] = False if compute_node not in configuration_error: configuration_error.append(compute_node) cret.pop('result', False) merge_results(ret, cret)
def dns_conf(output=True, ret=None): '''Prepare cloud controller dns (BIND) server''' func_name = 'mc_cloud_controller.dns_conf' __salt__['mc_api.time_log']('start {0}'.format(func_name)) if ret is None: ret = result() kw = {'ret': ret, 'output': output} kw['ret']['comment'] += green( 'Installing cloud controller DNS configuration\n') run_vt_hook('pre_dns_conf_on_controller', ret=kw['ret'], output=output) __salt__['mc_api.apply_sls']( ['makina-states.cloud.generic.controller.dnsconf'], **kw) check_point(kw['ret'], __opts__, output=output) run_vt_hook('post_dns_conf_on_controller', ret=kw['ret'], output=output) salt_output(kw['ret'], __opts__, output=output) __salt__['mc_api.time_log']('end {0}'.format(func_name)) return kw['ret']
def post_deploy(target, ret=None, output=True): '''Prepare cloud controller configuration can also apply per virtualization type configuration''' func_name = 'mc_compute_node.post_deploy {0}'.format(target) __salt__['mc_api.time_log']('start {0}'.format(func_name)) if ret is None: ret = result() hook = 'pre_post_deploy_compute_node' run_vt_hook(hook, ret=ret, target=target, output=output) for step in []: step(target, ret=ret, output=False) check_point(ret, __opts__, output=output) hook = 'post_post_deploy_compute_node' run_vt_hook(hook, ret=ret, target=target, output=output) salt_output(ret, __opts__, output=output) __salt__['mc_api.time_log']('end {0}'.format(func_name)) return ret
def deploy(output=True, ret=None): '''Prepare cloud controller configuration can also apply per virtualization type configuration''' func_name = 'mc_cloud_controller.deploy' __salt__['mc_api.time_log']('start {0}'.format(func_name)) if ret is None: ret = result() kw = {'ret': ret, 'output': output} kw['ret']['comment'] += green( 'Installing cloud controller configuration files\n') run_vt_hook('pre_deploy_controller', ret=kw['ret'], output=output) __salt__['mc_api.apply_sls']( ['makina-states.cloud.generic.controller', 'makina-states.cloud.saltify'], **kw) check_point(kw['ret'], __opts__, output=output) run_vt_hook('post_deploy_controller', ret=kw['ret'], output=output) salt_output(kw['ret'], __opts__, output=output) __salt__['mc_api.time_log']('end {0}'.format(func_name)) return kw['ret']
def run_vt_hook(hook_name, ret=None, target=None, vts=None, output=True, *args, **kwargs): '''Run an hook for a special vt on a controller, or a compute node or a vm''' func_name = ( 'mc_cloud_controller.run_vt_hook ' '{0} {1}').format(hook_name, target) __salt__['mc_api.time_log']('start {0}'.format(func_name)) if target: kwargs['target'] = target if ret is None: ret = result() if not vts: if not target: settings = cli('mc_cloud_controller.settings') vts = settings['vts'] else: settings = cli('mc_cloud_compute_node.settings') vts = settings['targets'][target]['virt_types'] if isinstance(vts, basestring): vts = [vts] for vt in vts: vid_ = 'mc_cloud_{0}.{1}'.format(vt, hook_name) if vid_ in __salt__: ret['comment'] += ( green('\n --> ') + blue(vid_) + green(' hook\n') ) kwargs['output'] = False cret = __salt__[vid_](*args, **kwargs) merge_results(ret, cret) check_point(ret, __opts__, output=output) __salt__['mc_api.time_log']('end {0}'.format(func_name)) return ret
def saltify(name, output=True, ret=None): '''Saltify a specific target''' if not ret: ret = result() try: already_exists = __salt__['mc_cloud_controller.exists'](name) data = None if already_exists: success = green('{0} is already saltified'.format(name)) else: try: data = cli('mc_cloud_saltify.settings_for_target', name) if not isinstance(data, dict): raise SaltyficationError(red('{0}'.format(data))) except KeyError: data = None if data is None: raise SaltyficationError( red('Saltify target {0} is not configured'.format(name))) else: success = green('{0} is saltified') kwargs = {'minion': {'master': data['master'], 'master_port': data['master_port']}} for var in [ "ssh_username", "ssh_keyfile", "keep_tmp", "gateway", "sudo", "password", "script_args", "ssh_host", "sudo_password", ]: if data.get(var): kwargs[var] = data[var] try: info = __salt__['cloud.profile']( data['profile'], [name], vm_overrides=kwargs) except Exception, exc: trace = traceback.format_exc() ret['trace'] = trace raise FailedStepError(red('{0}'.format(exc))) ret = process_cloud_return( name, info, driver='saltify', ret=ret) if ret['result']: ret['comment'] = success if not output: ret['changes'] = {} check_point(ret, __opts__) # once saltified, also be sure that this host had #a time to accomplish it's setup through a full initial # highstate if not cli('mc_cloud_compute_node.get_conf_for_target', name, 'saltified'): if data is None: data = cli('mc_cloud_saltify.settings_for_target', name) csettings = cli('mc_cloud.settings') proxycmd = '' if data.get('ssh_gateway', None): args = '-oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null' args += '-oControlPath=none' if 'ssh_key' in data: args += ' -i {0}'.format(data['ssh_key']) if 'ssh_port' in data: args += ' -p {0}'.format(data['ssh_port']) proxycmd = '-o\"ProxyCommand=ssh {1} {2} nc -w300 {1} 22\"'.format( data['ssh_gateway'], name, args ) cmd = ( 'ssh {2} {0} {1}/makina-states/_scripts/boot-salt.sh ' '--initial-highstate' ).format(name, csettings['root'], proxycmd) cmdret = cli('cmd.run_all', cmd) if cmdret['retcode']: ret['result'] = False ret['trace'] += 'Using cmd: \'{0}\''.format(cmd) ret['trace'] += '{0}\n'.format(cmdret['stdout']) ret['trace'] += '{0}\n'.format(cmdret['stderr']) ret['comment'] += red( 'SALTIFY: Error in highstate for {0}'.format(name)) check_point(ret, __opts__) # ok, marking initial highstate done cli('mc_cloud_compute_node.set_conf_for_target', name, 'saltified', True)
def orchestrate(skip=None, skip_vms=None, only=None, only_vms=None, no_dns_conf=False, no_configure=False, no_saltify=False, no_provision=False, no_vms=False, no_compute_node_provision=False, no_post_provision=False, no_vms_post_provision=False, output=True, refresh=True, ret=None): '''install controller, compute node, vms & run postdeploy no_configure skip configuring the cloud controller skip list of compute nodes to skip skip_vms list of vm to skip only explicit list of compute nodes to deploy only_vms explicit list of vm to deploy no_provision skip compute node & vm provision no_compute_node_provision skip configuration of compute nodes no_vms do not provision vms no_post_provision do not post provision compute nodes no_vms_post_provision do not post provision vms ''' func_name = 'mc_cloud_controller.orchestrate' __salt__['mc_api.time_log']('start {0}'.format(func_name)) only, only_vms, skip, skip_vms = ( __salt__['mc_cloud_controller.gather_only_skip']( only=only, only_vms=only_vms, skip=skip, skip_vms=skip_vms)) if ret is None: ret = result() if refresh: cli('saltutil.refresh_pillar') cret = result() try: # only deploy base configuration if we did not set # a specific saltify/computenode/vm switch if not no_dns_conf: dns_conf(output=False, ret=cret) check_point(cret, __opts__, output=output) del cret['result'] merge_results(ret, cret) if not no_configure: cret = result() # test that all hosts resolve else # for the dns migration deploy(output=False, ret=cret) check_point(cret, __opts__, output=output) del cret['result'] merge_results(ret, cret) if not no_saltify: cret = result() __salt__['mc_cloud_saltify.orchestrate']( only=only, skip=skip, ret=cret, output=False, refresh=False) del cret['result'] merge_results(ret, cret) cn_in_error = cret['changes'].get('saltified_errors', []) if not no_provision: if not skip: skip = [] skip += cn_in_error cret = result() __salt__['mc_cloud_compute_node.orchestrate']( skip=skip, skip_vms=skip_vms, only=only, only_vms=only_vms, no_provision=no_provision, no_compute_node_provision=no_compute_node_provision, no_post_provision=no_post_provision, no_vms_post_provision=no_vms_post_provision, no_vms=no_vms, refresh=False, output=False, ret=cret) del cret['result'] merge_results(ret, cret) cn_in_error = cret['changes'].get('provision_error', []) except FailedStepError: merge_results(ret, cret) trace = traceback.format_exc() ret['output'] += '\n{0}'.format(trace) salt_output(ret, __opts__, output=output) raise salt_output(ret, __opts__, output=output) __salt__['mc_api.time_log']('end {0}'.format(func_name)) return ret
if len(configuration_error): ret['comment'] += red('There were errors while configuring ' 'computes nodes {0}\n'.format( configuration_error)) else: if ret['result']: ret['trace'] = '' ret['comment'] += green('All computes nodes were preconfigured\n') # now for each reachable vm, also preconfigure it for idx, compute_node in enumerate(hosts_to_configure_vms): cret = result() try: __salt__['mc_cloud_vm.register_configurations']( compute_node, skip=skip_vms, only=only_vms, ret=cret, output=False) check_point(cret, __opts__, output=output) except FailedStepError: cret['result'] = False except Exception, exc: trace = traceback.format_exc() cret = {'result': False, 'output': ( 'unknown error on ' 'configuring vms {0}\n{1}' ).format(compute_node), 'comment': ( 'unknown error on configuring vms' '{0}\n' ).format(compute_node), 'trace': trace} if cret['result']: