Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: do not use namespace in node exporter systemd template #390

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

bigjazzsound
Copy link

I'm using ansible-core version 2.16.7 and the latest version of the collection.

When I run the task to install/config node-exporter:

- name: Manage node-exporter
  ansible.builtin.include_role:
    name: prometheus.prometheus.node_exporter

I get this error:

TASK [prometheus.prometheus.node_exporter : Copy the node_exporter systemd service file] *****************************************************************************
task path: <redacted>/collections/ansible_collections/prometheus/prometheus/roles/node_exporter/tasks/configure.yml:2
<redacted>
The full traceback is:
Traceback (most recent call last):
  File "<redacted>/venv/lib/python3.12/site-packages/ansible/template/__init__.py", line 1010, in do_template
    res = myenv.concat(rf)
          ^^^^^^^^^^^^^^^^
  File "<redacted>/venv/lib/python3.12/site-packages/ansible/template/native_helpers.py", line 83, in ansible_concat
    return ''.join([to_text(v) for v in nodes])
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<template>", line 156, in root
  File "<redacted>/venv/lib/python3.12/site-packages/ansible/template/__init__.py", line 381, in call
    return super().call(obj, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<redacted>/venv/lib/python3.12/site-packages/jinja2/runtime.py", line 303, in call
    return __obj(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^
TypeError: 'str' object is not callable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<redacted>/venv/lib/python3.12/site-packages/ansible/plugins/action/template.py", line 152, in run
    resultant = templar.do_template(template_data, preserve_trailing_newlines=True, escape_backslashes=False, overrides=overrides)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<redacted>/venv/lib/python3.12/site-packages/ansible/template/__init__.py", line 1021, in do_template
    raise AnsibleError("Unexpected templating type error occurred on (%s): %s" % (to_native(data), to_native(te)), orig_exc=te)
ansible.errors.AnsibleError: Unexpected templating type error occurred on ({{ ansible_managed | comment }}

[Unit]
Description=Prometheus Node Exporter
After=network-online.target

[Service]
Type=simple
User={{ node_exporter_system_user }}
Group={{ node_exporter_system_group }}
ExecStart={{ node_exporter_binary_install_dir }}/node_exporter \
{% for collector in node_exporter_enabled_collectors -%}
{%   if not collector is mapping %}
    '--collector.{{ collector }}' \
{%   else -%}
{%     set name, options = (collector.items()|list)[0] -%}
    '--collector.{{ name }}' \
{%     for k,v in options|dictsort %}
    '--collector.{{ name }}.{{ k }}={{ v }}' \
{%     endfor -%}
{%   endif -%}
{% endfor -%}
{% for collector in node_exporter_disabled_collectors %}
    '--no-collector.{{ collector }}' \
{% endfor %}
{% if node_exporter_tls_server_config | length > 0 or node_exporter_http_server_config | length > 0 or node_exporter_basic_auth_users | length > 0 %}
    {% if node_exporter_version is version('1.5.0', '>=') %}
    '--web.config.file=/etc/node_exporter/config.yaml' \
    {% else %}
    '--web.config=/etc/node_exporter/config.yaml' \
    {% endif %}
{% endif %}
{% if node_exporter_web_disable_exporter_metrics %}
    '--web.disable-exporter-metrics' \
{% endif %}
{% if node_exporter_version is version('1.5.0', '>=') and
      node_exporter_web_listen_address is iterable and
      node_exporter_web_listen_address is not mapping and
      node_exporter_web_listen_address is not string %}
{%   for address in node_exporter_web_listen_address %}
    '--web.listen-address={{ address }}' \
{%   endfor %}
{% else %}
    '--web.listen-address={{ node_exporter_web_listen_address }}' \
{% endif %}
    '--web.telemetry-path={{ node_exporter_web_telemetry_path }}'

SyslogIdentifier=node_exporter
Restart=always
RestartSec=1
StartLimitInterval=0

{% set ns = namespace(protect_home = 'yes') %}
{% for m in ansible_mounts if m.mount.startswith('/home') %}
{%   set ns.protect_home = 'read-only' %}
{% endfor %}
{% if node_exporter_textfile_dir.startswith('/home') %}
{%   set ns.protect_home = 'read-only' %}
{% endif %}
ProtectHome={{ ns.protect_home }}
NoNewPrivileges=yes

{% if (ansible_facts.packages.systemd | first).version is version('232', '>=') %}
ProtectSystem=strict
ProtectControlGroups=true
ProtectKernelModules=true
ProtectKernelTunables=yes
{% else %}
ProtectSystem=full
{% endif %}

[Install]
WantedBy=multi-user.target
): 'str' object is not callable. 'str' object is not callable
fatal: [dev-factory-svc-tenable-scan-candidate]: FAILED! => changed=false 
  msg: |-
    AnsibleError: Unexpected templating type error occurred on ({{ ansible_managed | comment }}
  
    [Unit]
    Description=Prometheus Node Exporter
    After=network-online.target
  
    [Service]
    Type=simple
    User={{ node_exporter_system_user }}
    Group={{ node_exporter_system_group }}
    ExecStart={{ node_exporter_binary_install_dir }}/node_exporter \
    {% for collector in node_exporter_enabled_collectors -%}
    {%   if not collector is mapping %}
        '--collector.{{ collector }}' \
    {%   else -%}
    {%     set name, options = (collector.items()|list)[0] -%}
        '--collector.{{ name }}' \
    {%     for k,v in options|dictsort %}
        '--collector.{{ name }}.{{ k }}={{ v }}' \
    {%     endfor -%}
    {%   endif -%}
    {% endfor -%}
    {% for collector in node_exporter_disabled_collectors %}
        '--no-collector.{{ collector }}' \
    {% endfor %}
    {% if node_exporter_tls_server_config | length > 0 or node_exporter_http_server_config | length > 0 or node_exporter_basic_auth_users | length > 0 %}
        {% if node_exporter_version is version('1.5.0', '>=') %}
        '--web.config.file=/etc/node_exporter/config.yaml' \
        {% else %}
        '--web.config=/etc/node_exporter/config.yaml' \
        {% endif %}
    {% endif %}
    {% if node_exporter_web_disable_exporter_metrics %}
        '--web.disable-exporter-metrics' \
    {% endif %}
    {% if node_exporter_version is version('1.5.0', '>=') and
          node_exporter_web_listen_address is iterable and
          node_exporter_web_listen_address is not mapping and
          node_exporter_web_listen_address is not string %}
    {%   for address in node_exporter_web_listen_address %}
        '--web.listen-address={{ address }}' \
    {%   endfor %}
    {% else %}
        '--web.listen-address={{ node_exporter_web_listen_address }}' \
    {% endif %}
        '--web.telemetry-path={{ node_exporter_web_telemetry_path }}'
  
    SyslogIdentifier=node_exporter
    Restart=always
    RestartSec=1
    StartLimitInterval=0
  
    {% set ns = namespace(protect_home = 'yes') %}
    {% for m in ansible_mounts if m.mount.startswith('/home') %}
    {%   set ns.protect_home = 'read-only' %}
    {% endfor %}
    {% if node_exporter_textfile_dir.startswith('/home') %}
    {%   set ns.protect_home = 'read-only' %}
    {% endif %}
    ProtectHome={{ ns.protect_home }}
    NoNewPrivileges=yes
  
    {% if (ansible_facts.packages.systemd | first).version is version('232', '>=') %}
    ProtectSystem=strict
    ProtectControlGroups=true
    ProtectKernelModules=true
    ProtectKernelTunables=yes
    {% else %}
    ProtectSystem=full
    {% endif %}
  
    [Install]
    WantedBy=multi-user.target
    ): 'str' object is not callable. 'str' object is not callable

Removing the use of jinja namespaces fixes the error.

Copy link
Member

@gardar gardar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks fine by me, not sure why we needed the namespace to begin with, although I'm not sure why you are running into this issue. What jinja2 version do you have installed?

@bigjazzsound
Copy link
Author

Looks fine by me, not sure why we needed the namespace to begin with, although I'm not sure why you are running into this issue. What jinja2 version do you have installed?

3.1.4

@gardar gardar requested a review from SuperQ October 23, 2024 17:55
@gardar
Copy link
Member

gardar commented Oct 23, 2024

The namespace is also used in the pushgateway and process_exporter roles, I guess we should get rid of it in them too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants