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
Exemple #2
0
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'] = ''
Exemple #3
0
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']: