Example #1
0
def install_node_exporter(state, host):
    if not host.data.node_exporter_version:
        raise DeployError(
            'No node_exporter_version set for this host, refusing to install node_exporter!',
        )

    server.user(
        state,
        host,
        {'Create the node_exporter user (Called prometheus by default)'},
        '{{ host.data.node_exporter_user }}',
        shell='/sbin/nologin',
    )

    files.directory(
        state,
        host,
        {'Ensure the node_exporter install directory exists'},
        '{{ host.data.node_exporter_install_dir }}',
        user=host.data.node_exporter_user,
        group=host.data.node_exporter_user,
    )

    # Work out the filename
    host.data.node_exporter_version_name = (
        'node_exporter-{0}.linux-'
        'amd64' if host.fact.arch == 'x86_64' else host.fact.arch).format(
            host.data.node_exporter_version)

    host.data.node_exporter_temp_filename = state.get_temp_filename(
        'node_exporter-{0}'.format(host.data.node_exporter_version), )

    download_node_exporter = files.download(
        state,
        host,
        {'Download node_exporter'},
        ('{{ host.data.node_exporter_download_base_url }}/'
         'v{{ host.data.node_exporter_version }}/'
         '{{ host.data.node_exporter_version_name }}.tar.gz'),
        '{{ host.data.node_exporter_temp_filename }}',
    )

    # If we downloaded node_exporter, extract it!
    if download_node_exporter.changed:
        server.shell(
            state,
            host,
            {'Extract node_exporter'},
            'tar -xzf {{ host.data.node_exporter_temp_filename }}'
            ' -C {{ host.data.node_exporter_install_dir }}',
        )

    files.link(
        state,
        host,
        {'Symlink node_exporter to /usr/bin'},
        '{{ host.data.node_exporter_bin_dir }}/node_exporter',  # link
        '{{ host.data.node_exporter_install_dir }}/'
        '{{ host.data.node_exporter_version_name }}/node_exporter',
    )
Example #2
0
def install_controller_services(state, host):
    apt.packages(
        state,
        host,
        {'Install packages'},
        [
            'apache2',
            'mariadb-server',
            'rabbitmq-server',
            'memcached',
            'python-memcache',
            'python-pymysql',
        ],
    )

    # MariaDB
    mariadb_configure = files.template(
        state,
        host,
        {'Generate MariaDB config'},
        get_template_path('mysql.cnf.j2'),
        '/etc/mysql/mariadb.conf.d/99-openstack.cnf',
    )

    init.service(
        state,
        host,
        {'Restart MariadB'},
        'mysql',
        restarted=mariadb_configure.changed,
    )

    # RabbitMQ
    server.shell(
        state,
        host,
        {'Setup RabbitMQ user'},
        (
            'rabbitmqctl add_user openstack {{ host.data.rabbitmq_password }} || true',
            'rabbitmqctl set_permissions openstack ".*" ".*" ".*"',
        ),
    )

    # Memcached
    memcached_configure = files.template(
        state,
        host,
        {'Generate memcached config'},
        get_template_path('memcached.conf.j2'),
        '/etc/memcached.conf',
    )

    init.service(
        state,
        host,
        {'Restart memcached'},
        'memcached',
        restarted=memcached_configure.changed,
    )
Example #3
0
def install_glance_service(state, host):
    install_glance = apt.packages(
        state,
        host,
        {'Install glance'},
        ['glance'],
    )

    if install_glance.changed:
        create_database(state, host, 'glance')
        create_service_user(state, host, 'glance', 'image')
        create_service_endpoints(state, host, 'image', ':9292')

    generate_glance_api_config = files.template(
        state,
        host,
        {'Generate glance-api config'},
        get_template_path('glance-api.conf.j2'),
        '/etc/glance/glance-api.conf',
    )

    generate_glance_registry_config = files.template(
        state,
        host,
        {'Generate glance-registry config'},
        get_template_path('glance-registry.conf.j2'),
        '/etc/glance/glance-registry.conf',
    )

    server.shell(
        state,
        host,
        {'Sync the glance database'},
        'glance-manage db_sync',
    )

    should_restart_glance = (generate_glance_api_config.changed
                             or generate_glance_registry_config.changed)

    init.service(
        state,
        host,
        {'Restart glance-registry'},
        'glance-registry',
        restarted=should_restart_glance,
    )

    init.service(
        state,
        host,
        {'Restart glance-api'},
        'glance-api',
        restarted=should_restart_glance,
    )
Example #4
0
def install_neutron_service(state, host, nova=False, placement=False):
    create_database(state, host, 'neutron')

    neutron_install = apt.packages(
        state,
        host,
        {'Install neutron network controller packages'},
        [
            'neutron-server',
            'neutron-plugin-ml2',
        ],
    )

    if neutron_install.changed:
        create_service_user(state, host, 'neutron', 'network')
        create_service_endpoints(state, host, 'network', ':9696')

    neutron_configure = files.template(
        state,
        host,
        {'Generate neutron config'},
        get_template_path('neutron-controller.conf.j2'),
        '/etc/neutron/neutron.conf',
        nova=nova,
    )

    ml2_plugin_configure = files.template(
        state,
        host,
        {'Generate neutron ml2 plugin config'},
        get_template_path('ml2_conf.ini.j2'),
        '/etc/neutron/plugins/ml2/ml2_conf.ini',
    )

    server.shell(
        {'Sync the neutron database'},
        '''
        neutron-db-manage --config-file /etc/neutron/neutron.conf \
            --config-file /etc/neutron/plugins/ml2/ml2_conf.ini \
            upgrade head
        ''',
    )

    init.service(
        state,
        host,
        {'Restart neutron-server'},
        'neutron-server',
        restarted=neutron_configure.changed or ml2_plugin_configure.changed,
    )
Example #5
0
def create_service_endpoints(state, host, name, port):
    server.shell(
        state,
        host,
        {'Create {0} service endpoints'.format(name)},
        (
            'openstack endpoint create --region RegionOne %s public http://{{ host.data.controller_host }}%s'
            % (name, port),  # noqa
            'openstack endpoint create --region RegionOne %s internal http://{{ host.data.controller_host }}%s'
            % (name, port),  # noqa
            'openstack endpoint create --region RegionOne %s admin http://{{ host.data.controller_host }}%s'
            % (name, port),  # noqa
        ),
        env=make_admin_env(host),
    )
Example #6
0
def create_service_user(state, host, name, type_):
    password = '******' % name

    server.shell(
        state,
        host,
        {'Create {0} {1} user/service'.format(name, type_)},
        (
            'openstack user create --domain default --password {0} {1}'.format(
                password, name),
            'openstack role add --project service --user {0} admin'.format(
                name),
            'openstack service create --name {0} {1}'.format(name, type_),
        ),
        env=make_admin_env(host),
    )
Example #7
0
def brook(state: Optional[State] = None, host: Optional[Host] = None) -> None:
    """Install brook."""
    if host.fact.arch == "x86_64":
        files.download(
            source_url=
            "https://github.com/txthinking/brook/releases/download/v20200909/brook_linux_amd64",  # noqa: E950
            destination="/usr/local/bin/brook",
            mode=755,
            sha256sum=
            "efc4dc925bcaff4d33450fbcd02351da8f971f5cea6b84501a3d2a6f94876adf",  # noqa: E950
            state=state,
            host=host,
        )
        server.shell(
            f"nohup brook server -l {_get_host_ip(host.name)}:{environ['BROOK_PORT']} -p {environ['BROOK_PASSWORD']} > /dev/null 2> /dev/null &",  # noqa: B950
            success_exit_codes=[0, 1],
            state=state,
            host=host,
        )
    else:
        python.raise_exception(state, host, NotImplementedError)
Example #8
0
def wireguard(state: Optional[State] = None,
              host: Optional[Host] = None) -> None:
    """Install wireguard."""
    if host.fact.os == "Linux":
        if host.fact.linux_distribution["release_meta"]["ID"] in [
                "debian", "ubuntu"
        ]:
            apt.packages(packages=["wireguard"], state=state, host=host)
        else:
            python.raise_exception(exception_class=NotImplementedError,
                                   state=state,
                                   host=host)
    else:
        python.raise_exception(exception_class=NotImplementedError,
                               state=state,
                               host=host)

    files.template(
        template_filename="templates/wg0.conf.j2",
        remote_filename="/etc/wireguard/wg0.conf",
        create_remote_dir=True,
        state=state,
        host=host,
        wg_private_key=environ["WG_PRIVATE_KEY"],
        wg_port=environ["WG_PORT"],
        wg_interface=environ["WG_INTERFACE"],
        wg_peer_1_public_key=environ["WG_PEER_1_PUBLIC_KEY"],
        wg_peer_2_public_key=environ["WG_PEER_2_PUBLIC_KEY"],
    )

    server.sysctl(key="net.ipv4.ip_forward", value=1, state=state, host=host)
    server.sysctl(key="net.ipv6.conf.all.forwarding",
                  value=1,
                  state=state,
                  host=host)
    server.shell(commands=["wg-quick up wg0"],
                 success_exit_codes=[0, 1],
                 state=state,
                 host=host)
Example #9
0
def ipv6(state: Optional[State] = None, host: Optional[Host] = None) -> None:
    """Test if ipv6 configured correctly."""
    server.shell(commands=["ping6 -c1 ::1"], state=state, host=host)
Example #10
0
    '/home/vagrant/example_files',
    user='******',
    group='pyinfra',
    delete=True,
    sudo=True,
)

# Generate files from local jinja2 templates
files.template(
    'templates/template.txt.j2',
    '/home/vagrant/template.txt',
)

# Execute arbitrary shell commands
server.shell([
    'echo "Shell command"',
    'echo "My hostname is {{ host.fact.hostname }}"',
])
# and scripts
server.script(
    'files/test.sh',
)

# Manage init systems
init.service(
    'cron',
    running=True,
    sudo=True,
    ignore_errors=True,
    on_error=on_pyinfra_error,
)
Example #11
0
        format(code_name),
    )

    # install kernel headers
    # Note: host.fact.os_version is the same as `uname -r` (ex: '4.15.0-72-generic')
    apt.packages(
        {
            'Install VirtualBox version {} and '
            'kernel headers for {}'.format(virtualbox_version,
                                           host.fact.os_version),
        },
        [
            'virtualbox-{}'.format(virtualbox_version),
            'linux-headers-{}'.format(host.fact.os_version),
        ],
        update=True,
    )

    server.shell(
        {
            'Run vboxconfig which will stop/start VirtualBox services and build kernel modules'
        },
        '/sbin/vboxconfig',
    )

    python.call(
        {'Verify VirtualBox version'},
        verify_virtualbox_version,
        version=virtualbox_version,
    )
Example #12
0
from pyinfra.modules import server

SUDO = True

# Various different outputs

# To see output need to run pyinfra with '-v'
a = server.script(
    {'Hello'},
    'files/hello.bash',
)
print('a', a)

# To see output need to run pyinfra with '-v'
b = server.shell(
    {'Say Hello'},
    'echo Hello',
)
print('b', b)
Example #13
0
from pyinfra import host, local, state
from pyinfra.modules import files, server

server.shell(
    {'First main operation'},
    'echo first_main_op',
)

# Create some conditional branches
if host.name == 'somehost':
    server.shell(
        {'Second main operation'},
        'echo second_main_op',
    )
elif host.name == 'anotherhost':
    local.include('tasks/a_task.py')

# Include the whole file again, but for all hosts
local.include('tasks/a_task.py')

# Do a loop which will generate duplicate op hashes
for i in range(2):
    server.shell(
        {'Loop-{0} main operation'.format(i)},
        'echo loop_{0}_main_operation'.format(i),
    )

files.file(
    {'Third main operation'},
    'files/a_file',
    '/a_file',
Example #14
0
def install_keystone_service(state, host):
    create_database(state, host, 'keystone')

    keystone_install = apt.packages(
        state, host,
        {'Install keystone'},
        ['keystone'],
    )

    files.template(
        state, host,
        {'Generate keystone config'},
        get_template_path('keystone.conf.j2'),
        '/etc/keystone/keystone.conf',
    )

    server.shell(
        state, host,
        {'Sync the keystone database'},
        'keystone-manage db_sync',
    )

    # Bootstrap keystone: only do this if newly installed
    if keystone_install.changed:
        server.shell(
            state, host, '''
keystone-manage fernet_setup --keystone-user keystone --keystone-group keystone
keystone-manage credential_setup --keystone-user keystone --keystone-group keystone

keystone-manage bootstrap \
     --bootstrap-password {{ host.data.admin_password }} \
    --bootstrap-admin-url http://{{ host.data.controller_host }}:35357/v3/ \
    --bootstrap-internal-url http://{{ host.data.controller_host }}:35357/v3/ \
    --bootstrap-public-url http://{{ host.data.controller_host }}:5000/v3/ \
    --bootstrap-region-id RegionOne
        ''')

    update_apache_config = files.line(
        state, host,
        {'Set ServerName in apache2 config'},
        '/etc/apache2/apache2.conf',
        'ServerName.*',
        replace='ServerName {{ host.data.ssh_hostname }}',
    )

    init.service(
        state, host,
        {'Restart apache2'},
        'apache2',
        restarted=update_apache_config.changed,
    )

    if keystone_install.changed:
        server.shell(
            state, host,
            {'Create initial projects/users/roles'},
            (
                'openstack project create --domain default service',
                'openstack project create --domain default user',
                'openstack user create --domain default --password hamble user-1',
                'openstack role create user',
                'openstack role add --project user --user user-1 user',
            ),
            env=make_admin_env(host),
        )
Example #15
0
    files.directory(
        {'Ensure the `{}` exists'.format(tftp_dir)},
        tftp_dir,
    )

    tar_file = 'netboot.tar.gz'
    tar_file_full_path = '/tmp/{}'.format(tar_file)
    files.download(
        {'Download `{}`'.format(tar_file)},
        'http://archive.ubuntu.com/ubuntu/dists/bionic-updates/main/'
        'installer-amd64/current/images/netboot/{}'.format(tar_file),
        tar_file_full_path,
    )

    server.shell(
        {'Extract files from tar file'},
        'tar -xvzf {} -C {}'.format(tar_file_full_path, tftp_dir),
    )

    server.shell(
        {'Change permissions'},
        'chown -R nobody:nogroup {}'.format(tftp_dir),
    )

    uefi_file = 'grubnetx64.efi.signed'
    uefi_full_path = '{}/{}'.format(tftp_dir, uefi_file)
    files.download(
        {'Download `{}`'.format(uefi_file)},
        'http://archive.ubuntu.com/ubuntu/dists/trusty/main/'
        'uefi/grub2-amd64/current/grubnetx64.efi.signed',
        uefi_full_path,
    )
Example #16
0
# Copy local files to remote host
files.put('files/file.txt', '/home/vagrant/file.txt', mode=777)
# and sync directories
files.sync('files',
           '/home/vagrant/example_files',
           user='******',
           group='pyinfra',
           delete=True,
           sudo=True)

# Generate files from local jinja2 templates
files.template('templates/template.txt.j2', '/home/vagrant/template.txt')

# Execute arbitrary shell commands
server.shell(
    ['echo "Shell command"', 'echo "My hostname is {{ host.fact.hostname }}"'])
# and scripts
server.script('files/test.sh')

# Manage init systems
init.d('crond', running=True, sudo=True, ignore_errors=True)

# Include roles
local.include(
    'roles/bsd_role.py',
    hosts=inventory.bsd  # optionally limit the role to a subset of hosts
)

# Storing this fact to avoid typing it so much (because the example targets a whole bunch
# of distros [& 2 OSs]).
distro = host.fact.linux_distribution
Example #17
0
from pyinfra.modules import server


server.shell(
    {'First task operation'},
    'echo first_task_operation',
)

server.shell(
    {'Second task operation'},
    'echo second_task_operation',
)
Example #18
0
def install_etcd(state, host):
    if not host.data.etcd_version:
        raise DeployError(
            'No etcd_version set for this host, refusing to install etcd!', )

    server.user(
        state,
        host,
        {'Create the etcd user'},
        'etcd',
        shell='/sbin/nologin',
    )

    files.directory(
        state,
        host,
        {'Ensure the etcd data directory exists'},
        '{{ host.data.etcd_data_dir }}',
        user=host.data.etcd_user,
        group=host.data.etcd_user,
    )

    files.directory(
        state,
        host,
        {'Ensure the etcd install directory exists'},
        host.data.etcd_install_dir,
        user=host.data.etcd_user,
        group=host.data.etcd_user,
    )

    # Work out the filename
    host.data.etcd_version_name = ('etcd-{0}-linux-'
                                   'amd64' if host.fact.arch == 'x86_64' else
                                   host.fact.arch).format(
                                       host.data.etcd_version)

    host.data.etcd_temp_filename = state.get_temp_filename(
        'etcd-{0}'.format(host.data.etcd_version), )

    download_etcd = files.download(
        state,
        host,
        {'Download etcd'},
        ('{{ host.data.etcd_download_base_url }}/'
         '{{ host.data.etcd_version }}/'
         '{{ host.data.etcd_version_name }}.tar.gz'),
        '{{ host.data.etcd_temp_filename }}',
    )

    # If we downloaded etcd, extract it!
    server.shell(
        state,
        host,
        {'Extract etcd'},
        'tar -xzf {{ host.data.etcd_temp_filename }} -C {{ host.data.etcd_install_dir }}',
        when=download_etcd.changed,
    )

    files.link(
        state,
        host,
        {'Symlink etcd to /usr/bin'},
        '{{ host.data.etcd_bin_dir }}/etcd',  # link
        '{{ host.data.etcd_install_dir }}/{{ host.data.etcd_version_name }}/etcd',
    )

    files.link(
        state,
        host,
        {'Symlink etcdctl to {0}'.format(host.data.etcd_bin_dir)},
        '{{ host.data.etcd_bin_dir }}/etcdctl',
        '{{ host.data.etcd_install_dir }}/{{ host.data.etcd_version_name }}/etcdctl',
    )
Example #19
0
from pyinfra.modules import files, server

CONNECT_TIMEOUT = 1
FAIL_PERCENT = 0

server.user(
    {'Add pyinfra user'},
    'pyinfra',
    home='/home/pyinfra',
    shell='/bin/bash',
)

files.file(
    {'Add log file'},
    '/var/log/pyinfra.log',
    user='******',
    mode=777,
)

files.put(
    {'Copy a file'},
    '../files/test_file.txt',
    '/home/pyinfra/test_file.txt',
    user='******',
)

server.shell(
    {'Run some shell'},
    'echo "hi!"',
)