コード例 #1
0
def template(
    state, host, template_filename, remote_filename,
    user=None, group=None, mode=None, **data
):
    '''
    Generate a template and write it to the remote system.

    + template_filename: local template filename
    + remote_filename: remote filename
    + user: user to own the files
    + group: group to own the files
    + mode: permissions of the files
    '''

    if state.deploy_dir:
        template_filename = path.join(state.deploy_dir, template_filename)

    # Load the template into memory
    template = get_template(template_filename)

    # Ensure host is always available inside templates
    data['host'] = host
    data['inventory'] = state.inventory

    # Render and make file-like it's output
    try:
        output = template.render(data)
    except UndefinedError as e:
        _, _, trace = sys.exc_info()

        # Jump through to the *second last* traceback, which contains the line number
        # of the error within the in-memory Template object
        while trace.tb_next:
            if trace.tb_next.tb_next:
                trace = trace.tb_next
            else:
                break

        line_number = trace.tb_frame.f_lineno

        # Quickly read the line in question and one above/below for nicer debugging
        template_lines = open(template_filename, 'r').readlines()
        template_lines = [line.strip() for line in template_lines]
        relevant_lines = template_lines[max(line_number - 2, 0):line_number + 1]

        raise OperationError('Error in template: {0} (L{1}): {2}\n...\n{3}\n...'.format(
            template_filename, line_number, e, '\n'.join(relevant_lines),
        ))

    output_file = six.StringIO(output)
    # Set the name attribute for nicer debugging
    output_file.name = template_filename

    # Pass to the put function
    yield put(
        state, host,
        output_file, remote_filename,
        user=user, group=group, mode=mode,
        add_deploy_dir=False,
    )
コード例 #2
0
def template(src,
             dest,
             user=None,
             group=None,
             mode=None,
             create_remote_dir=True,
             state=None,
             host=None,
             **data):
    '''
    Generate a template using jinja2 and write it to the remote system.

    + src: local template filename
    + dest: remote filename
    + user: user to own the files
    + group: group to own the files
    + mode: permissions of the files
    + create_remote_dir: create the remote directory if it doesn't exist

    ``create_remote_dir``:
        If the remote directory does not exist it will be created using the same
        user & group as passed to ``files.put``. The mode will *not* be copied over,
        if this is required call ``files.directory`` separately.

    Notes:
       Common convention is to store templates in a "templates" directory and
       have a filename suffix with '.j2' (for jinja2).

       For information on the template syntax, see
       `the jinja2 docs <https://jinja.palletsprojects.com>`_.

    Examples:

    .. code:: python

        files.template(
            name='Create a templated file',
            src='templates/somefile.conf.j2',
            dest='/etc/somefile.conf',
        )

        files.template(
            name='Create service file',
            src='templates/myweb.service.j2',
            dest='/etc/systemd/system/myweb.service',
            mode='755',
            user='******',
            group='root',
        )

        # Example showing how to pass python variable to template file.
        # The .j2 file can use `{{ foo_variable }}` to be interpolated.
        foo_variable = 'This is some foo variable contents'
        files.template(
            name='Create a templated file',
            src='templates/foo.j2',
            dest='/tmp/foo',
            foo_variable=foo_variable,
        )
    '''

    dest = escape_unix_path(dest)

    if state.deploy_dir:
        src = os_path.join(state.deploy_dir, src)

    # Ensure host is always available inside templates
    data['host'] = host
    data['inventory'] = state.inventory

    # Render and make file-like it's output
    try:
        output = get_template(src).render(data)
    except (TemplateSyntaxError, UndefinedError) as e:
        _, _, trace = sys.exc_info()

        # Jump through to the *second last* traceback, which contains the line number
        # of the error within the in-memory Template object
        while trace.tb_next:
            if trace.tb_next.tb_next:
                trace = trace.tb_next
            else:  # pragma: no cover
                break

        line_number = trace.tb_frame.f_lineno

        # Quickly read the line in question and one above/below for nicer debugging
        with open(src, 'r') as f:
            template_lines = f.readlines()

        template_lines = [line.strip() for line in template_lines]
        relevant_lines = template_lines[max(line_number - 2, 0):line_number +
                                        1]

        raise OperationError(
            'Error in template: {0} (L{1}): {2}\n...\n{3}\n...'.format(
                src,
                line_number,
                e,
                '\n'.join(relevant_lines),
            ))

    output_file = six.StringIO(output)
    # Set the template attribute for nicer debugging
    output_file.template = src

    # Pass to the put function
    yield put(
        output_file,
        dest,
        user=user,
        group=group,
        mode=mode,
        add_deploy_dir=False,
        create_remote_dir=create_remote_dir,
        state=state,
        host=host,
    )
コード例 #3
0
ファイル: files.py プロジェクト: morrison12/pyinfra
def template(src,
             dest,
             user=None,
             group=None,
             mode=None,
             create_remote_dir=True,
             **data):
    '''
    Generate a template using jinja2 and write it to the remote system.

    + src: template filename or IO-like object
    + dest: remote filename
    + user: user to own the files
    + group: group to own the files
    + mode: permissions of the files
    + create_remote_dir: create the remote directory if it doesn't exist

    ``create_remote_dir``:
        If the remote directory does not exist it will be created using the same
        user & group as passed to ``files.put``. The mode will *not* be copied over,
        if this is required call ``files.directory`` separately.

    Notes:
       Common convention is to store templates in a "templates" directory and
       have a filename suffix with '.j2' (for jinja2).

       For information on the template syntax, see
       `the jinja2 docs <https://jinja.palletsprojects.com>`_.

    **Examples:**

    .. code:: python

        files.template(
            name="Create a templated file",
            src="templates/somefile.conf.j2",
            dest="/etc/somefile.conf",
        )

        files.template(
            name="Create service file",
            src="templates/myweb.service.j2",
            dest="/etc/systemd/system/myweb.service",
            mode="755",
            user="******",
            group="root",
        )

        # Example showing how to pass python variable to template file. You can also
        # use dicts and lists. The .j2 file can use `{{ foo_variable }}` to be interpolated.
        foo_variable = 'This is some foo variable contents'
        foo_dict = {
            "str1": "This is string 1",
            "str2": "This is string 2"
        }
        foo_list = [
            "entry 1",
            "entry 2"
        ]

        template = StringIO("""
        name: "{{ foo_variable }}"
        dict_contents:
            str1: "{{ foo_dict.str1 }}"
            str2: "{{ foo_dict.str2 }}"
        list_contents:
        {% for entry in foo_list %}
            - "{{ entry }}"
        {% endfor %}
        """)

        files.template(
            name="Create a templated file",
            src=template,
            dest="/tmp/foo.yml",
            foo_variable=foo_variable,
            foo_dict=foo_dict,
            foo_list=foo_list
        )
    '''

    if not hasattr(src, "read") and state.cwd:
        src = os.path.join(state.cwd, src)

    # Ensure host/state/inventory are available inside templates (if not set)
    data.setdefault("host", host)
    data.setdefault("state", state)
    data.setdefault("inventory", state.inventory)
    data.setdefault("facts", pyinfra.facts)

    # Render and make file-like it's output
    try:
        output = get_template(src).render(data)
    except (TemplateRuntimeError, TemplateSyntaxError, UndefinedError) as e:
        trace_frames = traceback.extract_tb(sys.exc_info()[2])
        trace_frames = [
            frame for frame in trace_frames
            if frame[2] in ("template", "<module>", "top-level template code")
        ]  # thank you https://github.com/saltstack/salt/blob/master/salt/utils/templates.py

        line_number = trace_frames[-1][1]

        # Quickly read the line in question and one above/below for nicer debugging
        with open(src, "r") as f:
            template_lines = f.readlines()

        template_lines = [line.strip() for line in template_lines]
        relevant_lines = template_lines[max(line_number - 2, 0):line_number +
                                        1]

        raise OperationError(
            "Error in template: {0} (L{1}): {2}\n...\n{3}\n...".format(
                src,
                line_number,
                e,
                "\n".join(relevant_lines),
            ), )

    output_file = StringIO(output)
    # Set the template attribute for nicer debugging
    output_file.template = src

    # Pass to the put function
    yield from put(
        output_file,
        dest,
        user=user,
        group=group,
        mode=mode,
        add_deploy_dir=False,
        create_remote_dir=create_remote_dir,
    )
コード例 #4
0
def template(
    src, dest,
    user=None, group=None, mode=None, create_remote_dir=True,
    state=None, host=None,
    **data
):
    '''
    Generate a template using jinja2 and write it to the remote system.

    + src: local template filename
    + dest: remote filename
    + user: user to own the files
    + group: group to own the files
    + mode: permissions of the files
    + create_remote_dir: create the remote directory if it doesn't exist

    ``create_remote_dir``:
        If the remote directory does not exist it will be created using the same
        user & group as passed to ``files.put``. The mode will *not* be copied over,
        if this is required call ``files.directory`` separately.

    Notes:
       Common convention is to store templates in a "templates" directory and
       have a filename suffix with '.j2' (for jinja2).

       For information on the template syntax, see
       `the jinja2 docs <https://jinja.palletsprojects.com>`_.

    Examples:

    .. code:: python

        files.template(
            name='Create a templated file',
            src='templates/somefile.conf.j2',
            dest='/etc/somefile.conf',
        )

        files.template(
            name='Create service file',
            src='templates/myweb.service.j2',
            dest='/etc/systemd/system/myweb.service',
            mode='755',
            user='******',
            group='root',
        )

        # Example showing how to pass python variable to template file.
        # The .j2 file can use `{{ foo_variable }}` to be interpolated.
        foo_variable = 'This is some foo variable contents'
        files.template(
            name='Create a templated file',
            src='templates/foo.j2',
            dest='/tmp/foo',
            foo_variable=foo_variable,
        )
    '''

    dest = escape_unix_path(dest)

    if state.deploy_dir:
        src = os_path.join(state.deploy_dir, src)

    # Ensure host/state/inventory are available inside templates (if not set)
    data.setdefault('host', host)
    data.setdefault('state', state)
    data.setdefault('inventory', state.inventory)

    # Render and make file-like it's output
    try:
        output = get_template(src).render(data)
    except (TemplateRuntimeError, TemplateSyntaxError, UndefinedError) as e:
        trace_frames = traceback.extract_tb(sys.exc_info()[2])
        trace_frames = [
            frame for frame in trace_frames
            if frame[2] in ('template', '<module>', 'top-level template code')
        ]  # thank you https://github.com/saltstack/salt/blob/master/salt/utils/templates.py

        line_number = trace_frames[-1][1]

        # Quickly read the line in question and one above/below for nicer debugging
        with open(src, 'r') as f:
            template_lines = f.readlines()

        template_lines = [line.strip() for line in template_lines]
        relevant_lines = template_lines[max(line_number - 2, 0):line_number + 1]

        raise OperationError('Error in template: {0} (L{1}): {2}\n...\n{3}\n...'.format(
            src, line_number, e, '\n'.join(relevant_lines),
        ))

    output_file = six.StringIO(output)
    # Set the template attribute for nicer debugging
    output_file.template = src

    # Pass to the put function
    yield put(
        output_file, dest,
        user=user, group=group, mode=mode,
        add_deploy_dir=False,
        create_remote_dir=create_remote_dir,
        state=state, host=host,
    )
コード例 #5
0
                config=VaultAutoAuthAWS(
                    role=
                    f"concourse-{concourse_config._node_type}"  # noqa: WPS437
                ),
            ),
            sinks=[
                VaultAutoAuthSink(type="file", config=VaultAutoAuthFileSink())
            ],
        ),
        template=[
            partial_func() for partial_func in vault_template_map[node_type]
        ] + [
            VaultTemplate(
                contents=get_template(
                    "{% for env_var, env_value in concourse_env.items() -%}\n"
                    "{{ env_var }}={{ env_value }}\n{% endfor -%}",
                    is_string=True,
                ).render(concourse_env=concourse_config.concourse_env()),
                destination=concourse_base_config.env_file_path,
            ),
        ],
    )),
    Consul(version=VERSIONS["consul"], configuration=consul_configuration),
]
install_hashicorp_products(hashicorp_products)

# Manage services
if host.fact.has_systemd:
    register_concourse_service(concourse_config,
                               restart=concourse_install_changed
                               or concourse_config_changed)