Example #1
0
def handle(name, cfg, cloud, log, _args):
    # If there isn't a puppet key in the configuration don't do anything
    if 'puppet' not in cfg:
        log.debug(("Skipping module named %s,"
                   " no 'puppet' configuration found"), name)
        return

    puppet_cfg = cfg['puppet']
    # Start by installing the puppet package if necessary...
    install = util.get_cfg_option_bool(puppet_cfg, 'install', True)
    version = util.get_cfg_option_str(puppet_cfg, 'version', None)
    collection = util.get_cfg_option_str(puppet_cfg, 'collection', None)
    install_type = util.get_cfg_option_str(puppet_cfg, 'install_type',
                                           'packages')
    cleanup = util.get_cfg_option_bool(puppet_cfg, 'cleanup', True)
    run = util.get_cfg_option_bool(puppet_cfg, 'exec', default=False)
    aio_install_url = util.get_cfg_option_str(puppet_cfg,
                                              'aio_install_url',
                                              default=AIO_INSTALL_URL)

    # AIO and distro packages use different paths
    if install_type == 'aio':
        puppet_user = '******'
        puppet_bin = '/opt/puppetlabs/bin/puppet'
        puppet_package = 'puppet-agent'
    else:  # default to 'packages'
        puppet_user = '******'
        puppet_bin = 'puppet'
        puppet_package = 'puppet'

    package_name = util.get_cfg_option_str(puppet_cfg, 'package_name',
                                           puppet_package)
    if not install and version:
        log.warning(("Puppet install set to false but version supplied,"
                     " doing nothing."))
    elif install:
        log.debug(("Attempting to install puppet %s from %s"),
                  version if version else 'latest', install_type)

        if install_type == "packages":
            cloud.distro.install_packages((package_name, version))
        elif install_type == "aio":
            install_puppet_aio(aio_install_url, version, collection, cleanup)
        else:
            log.warning("Unknown puppet install type '%s'", install_type)
            run = False

    conf_file = util.get_cfg_option_str(puppet_cfg, 'conf_file',
                                        get_config_value(puppet_bin, 'config'))
    ssl_dir = util.get_cfg_option_str(puppet_cfg, 'ssl_dir',
                                      get_config_value(puppet_bin, 'ssldir'))
    csr_attributes_path = util.get_cfg_option_str(
        puppet_cfg, 'csr_attributes_path',
        get_config_value(puppet_bin, 'csr_attributes'))

    p_constants = PuppetConstants(conf_file, ssl_dir, csr_attributes_path, log)

    # ... and then update the puppet configuration
    if 'conf' in puppet_cfg:
        # Add all sections from the conf object to puppet.conf
        contents = util.load_file(p_constants.conf_path)
        # Create object for reading puppet.conf values
        puppet_config = helpers.DefaultingConfigParser()
        # Read puppet.conf values from original file in order to be able to
        # mix the rest up. First clean them up
        # (TODO(harlowja) is this really needed??)
        cleaned_lines = [i.lstrip() for i in contents.splitlines()]
        cleaned_contents = '\n'.join(cleaned_lines)
        # Move to puppet_config.read_file when dropping py2.7
        puppet_config.read_file(StringIO(cleaned_contents),
                                source=p_constants.conf_path)
        for (cfg_name, cfg) in puppet_cfg['conf'].items():
            # Cert configuration is a special case
            # Dump the puppetserver ca certificate in the correct place
            if cfg_name == 'ca_cert':
                # Puppet ssl sub-directory isn't created yet
                # Create it with the proper permissions and ownership
                util.ensure_dir(p_constants.ssl_dir, 0o771)
                util.chownbyname(p_constants.ssl_dir, puppet_user, 'root')
                util.ensure_dir(p_constants.ssl_cert_dir)

                util.chownbyname(p_constants.ssl_cert_dir, puppet_user, 'root')
                util.write_file(p_constants.ssl_cert_path, cfg)
                util.chownbyname(p_constants.ssl_cert_path, puppet_user,
                                 'root')
            else:
                # Iterate through the config items, we'll use ConfigParser.set
                # to overwrite or create new items as needed
                for (o, v) in cfg.items():
                    if o == 'certname':
                        # Expand %f as the fqdn
                        # TODO(harlowja) should this use the cloud fqdn??
                        v = v.replace("%f", socket.getfqdn())
                        # Expand %i as the instance id
                        v = v.replace("%i", cloud.get_instance_id())
                        # certname needs to be downcased
                        v = v.lower()
                    puppet_config.set(cfg_name, o, v)
            # We got all our config as wanted we'll rename
            # the previous puppet.conf and create our new one
            util.rename(p_constants.conf_path,
                        "%s.old" % (p_constants.conf_path))
            util.write_file(p_constants.conf_path, puppet_config.stringify())

    if 'csr_attributes' in puppet_cfg:
        util.write_file(
            p_constants.csr_attributes_path,
            yaml.dump(puppet_cfg['csr_attributes'], default_flow_style=False))

    # Set it up so it autostarts
    _autostart_puppet(log)

    # Run the agent if needed
    if run:
        log.debug('Running puppet-agent')
        cmd = [puppet_bin, 'agent']
        if 'exec_args' in puppet_cfg:
            cmd_args = puppet_cfg['exec_args']
            if isinstance(cmd_args, (list, tuple)):
                cmd.extend(cmd_args)
            elif isinstance(cmd_args, str):
                cmd.extend(cmd_args.split())
            else:
                log.warning(
                    "Unknown type %s provided for puppet"
                    " 'exec_args' expected list, tuple,"
                    " or string", type(cmd_args))
                cmd.extend(PUPPET_AGENT_DEFAULT_ARGS)
        else:
            cmd.extend(PUPPET_AGENT_DEFAULT_ARGS)
        subp.subp(cmd, capture=False)

    # Start puppetd
    subp.subp(['service', 'puppet', 'start'], capture=False)
def handle(name, cfg, cloud, log, _args):
    # If there isn't a puppet key in the configuration don't do anything
    if 'puppet' not in cfg:
        log.debug(("Skipping module named %s,"
                   " no 'puppet' configuration found"), name)
        return

    puppet_cfg = cfg['puppet']

    # Start by installing the puppet package if necessary...
    install = util.get_cfg_option_bool(puppet_cfg, 'install', True)
    version = util.get_cfg_option_str(puppet_cfg, 'version', None)
    if not install and version:
        log.warn(("Puppet install set false but version supplied,"
                  " doing nothing."))
    elif install:
        log.debug(("Attempting to install puppet %s,"),
                  version if version else 'latest')
        cloud.distro.install_packages(('puppet', version))

    # ... and then update the puppet configuration
    if 'conf' in puppet_cfg:
        # Add all sections from the conf object to puppet.conf
        contents = util.load_file(PUPPET_CONF_PATH)
        # Create object for reading puppet.conf values
        puppet_config = helpers.DefaultingConfigParser()
        # Read puppet.conf values from original file in order to be able to
        # mix the rest up. First clean them up
        # (TODO(harlowja) is this really needed??)
        cleaned_lines = [i.lstrip() for i in contents.splitlines()]
        cleaned_contents = '\n'.join(cleaned_lines)
        puppet_config.readfp(StringIO(cleaned_contents),
                             filename=PUPPET_CONF_PATH)
        for (cfg_name, cfg) in puppet_cfg['conf'].iteritems():
            # Cert configuration is a special case
            # Dump the puppet master ca certificate in the correct place
            if cfg_name == 'ca_cert':
                # Puppet ssl sub-directory isn't created yet
                # Create it with the proper permissions and ownership
                util.ensure_dir(PUPPET_SSL_DIR, 0771)
                util.chownbyname(PUPPET_SSL_DIR, 'puppet', 'root')
                util.ensure_dir(PUPPET_SSL_CERT_DIR)
                util.chownbyname(PUPPET_SSL_CERT_DIR, 'puppet', 'root')
                util.write_file(PUPPET_SSL_CERT_PATH, str(cfg))
                util.chownbyname(PUPPET_SSL_CERT_PATH, 'puppet', 'root')
            else:
                # Iterate throug the config items, we'll use ConfigParser.set
                # to overwrite or create new items as needed
                for (o, v) in cfg.iteritems():
                    if o == 'certname':
                        # Expand %f as the fqdn
                        # TODO(harlowja) should this use the cloud fqdn??
                        v = v.replace("%f", socket.getfqdn())
                        # Expand %i as the instance id
                        v = v.replace("%i", cloud.get_instance_id())
                        # certname needs to be downcased
                        v = v.lower()
                    puppet_config.set(cfg_name, o, v)
            # We got all our config as wanted we'll rename
            # the previous puppet.conf and create our new one
            util.rename(PUPPET_CONF_PATH, "%s.old" % (PUPPET_CONF_PATH))
            util.write_file(PUPPET_CONF_PATH, puppet_config.stringify())

    # Set it up so it autostarts
    _autostart_puppet(log)

    # Start puppetd
    util.subp(['service', 'puppet', 'start'], capture=False)