From 343ab984515ea322f71a2ac29843a2a7303c15af Mon Sep 17 00:00:00 2001 From: SuperQ Date: Tue, 22 Aug 2023 15:11:32 +0200 Subject: [PATCH] fix: Make binary installs consistent Update the blackbox_exporter and snmp_exporter installs to be consistent with other exporter package installs. Signed-off-by: SuperQ --- roles/blackbox_exporter/defaults/main.yml | 1 + .../blackbox_exporter/meta/argument_specs.yml | 7 +- .../molecule/latest/molecule.yml | 6 ++ .../molecule/latest/tests/test_latest.py | 37 +++++++++ roles/blackbox_exporter/tasks/install.yml | 71 ++++++++++++------ roles/blackbox_exporter/tasks/preflight.yml | 31 ++++++++ roles/snmp_exporter/defaults/main.yml | 1 + roles/snmp_exporter/meta/argument_specs.yml | 7 +- roles/snmp_exporter/tasks/install.yml | 75 ++++++++++++------- roles/snmp_exporter/tasks/preflight.yml | 32 ++++++-- 10 files changed, 208 insertions(+), 60 deletions(-) create mode 100644 roles/blackbox_exporter/molecule/latest/molecule.yml create mode 100644 roles/blackbox_exporter/molecule/latest/tests/test_latest.py diff --git a/roles/blackbox_exporter/defaults/main.yml b/roles/blackbox_exporter/defaults/main.yml index f3bf56f76..de2cacb40 100644 --- a/roles/blackbox_exporter/defaults/main.yml +++ b/roles/blackbox_exporter/defaults/main.yml @@ -1,5 +1,6 @@ --- blackbox_exporter_version: 0.24.0 +blackbox_exporter_binary_local_dir: "" blackbox_exporter_binary_url: "https://github.com/{{ _blackbox_exporter_repo }}/releases/download/v{{ blackbox_exporter_version }}/\ blackbox_exporter-{{ blackbox_exporter_version }}.linux-{{ go_arch_map[ansible_architecture] | default(ansible_architecture) }}.tar.gz" diff --git a/roles/blackbox_exporter/meta/argument_specs.yml b/roles/blackbox_exporter/meta/argument_specs.yml index ab97d1bfb..4f38c7f41 100644 --- a/roles/blackbox_exporter/meta/argument_specs.yml +++ b/roles/blackbox_exporter/meta/argument_specs.yml @@ -9,12 +9,17 @@ argument_specs: - "Prometheus Community" options: blackbox_exporter_version: - description: "Blackbox exporter package version" + description: "Blackbox exporter package version. Also accepts latest as parameter." default: "0.24.0" blackbox_exporter_skip_install: description: "Blackbox exporter installation tasks gets skipped when set to true." type: bool default: false + blackbox_exporter_binary_local_dir: + description: + - "Enables the use of local packages instead of those distributed on github." + - "The parameter may be set to a directory where the C(blackbox_exporter) binary is stored on the host where ansible is run." + - "This overrides the I(blackbox_exporter_version) parameter" blackbox_exporter_binary_url: description: "URL of the blackbox_exporter binaries .tar.gz file" default: "https://github.com/{{ _blackbox_exporter_repo }}/releases/download/v{{ blackbox_exporter_version }}/blackbox_exporter-{{ blackbox_exporter_version }}.linux-{{ go_arch_map[ansible_architecture] | default(ansible_architecture) }}.tar.gz" diff --git a/roles/blackbox_exporter/molecule/latest/molecule.yml b/roles/blackbox_exporter/molecule/latest/molecule.yml new file mode 100644 index 000000000..3e2b94705 --- /dev/null +++ b/roles/blackbox_exporter/molecule/latest/molecule.yml @@ -0,0 +1,6 @@ +--- +provisioner: + inventory: + group_vars: + all: + blackbox_exporter_version: latest diff --git a/roles/blackbox_exporter/molecule/latest/tests/test_latest.py b/roles/blackbox_exporter/molecule/latest/tests/test_latest.py new file mode 100644 index 000000000..8b5955eac --- /dev/null +++ b/roles/blackbox_exporter/molecule/latest/tests/test_latest.py @@ -0,0 +1,37 @@ +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import os +import testinfra.utils.ansible_runner +import pytest + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all') + + +@pytest.mark.parametrize("files", [ + "/etc/systemd/system/blackbox_exporter.service", + "/usr/local/bin/blackbox_exporter" +]) +def test_files(host, files): + f = host.file(files) + assert f.exists + assert f.is_file + + +def test_service(host): + s = host.service("blackbox_exporter") + try: + assert s.is_running + except AssertionError: + # Capture service logs + journal_output = host.run('journalctl -u blackbox_exporter --since "1 hour ago"') + print("\n==== journalctl -u blackbox_exporter Output ====\n") + print(journal_output) + print("\n============================================\n") + raise # Re-raise the original assertion error + + +def test_socket(host): + s = host.socket("tcp://0.0.0.0:9100") + assert s.is_listening diff --git a/roles/blackbox_exporter/tasks/install.yml b/roles/blackbox_exporter/tasks/install.yml index 777ae8a22..5d951f90f 100644 --- a/roles/blackbox_exporter/tasks/install.yml +++ b/roles/blackbox_exporter/tasks/install.yml @@ -15,33 +15,56 @@ createhome: false when: blackbox_exporter_user != 'root' -- name: Download blackbox exporter binary to local folder - become: false - ansible.builtin.unarchive: - src: "{{ blackbox_exporter_binary_url }}" - dest: "/tmp" - remote_src: true - creates: "/tmp/blackbox_exporter-{{ blackbox_exporter_version }}.linux-{{ go_arch_map[ansible_architecture] | default(ansible_architecture) }}/\ - blackbox_exporter" - register: _download_binary - until: _download_binary is succeeded - retries: 5 - delay: 2 - delegate_to: localhost - check_mode: false - when: not blackbox_exporter_skip_install +- name: Get binary + when: + - blackbox_exporter_binary_local_dir | length == 0 + - not blackbox_exporter_skip_install + block: + + - name: Download blackbox_exporter binary to local folder + become: false + ansible.builtin.get_url: + url: "{{ blackbox_exporter_binary_url }}" + dest: "/tmp/blackbox_exporter-{{ blackbox_exporter_version }}.linux-{{ go_arch }}.tar.gz" + checksum: "sha256:{{ __blackbox_exporter_checksum }}" + mode: '0644' + register: _download_binary + until: _download_binary is succeeded + retries: 5 + delay: 2 + delegate_to: localhost + check_mode: false -- name: Propagate blackbox exporter binary + - name: Unpack blackbox_exporter binary + become: false + ansible.builtin.unarchive: + src: "/tmp/blackbox_exporter-{{ blackbox_exporter_version }}.linux-{{ go_arch }}.tar.gz" + dest: "/tmp" + creates: "/tmp/blackbox_exporter-{{ blackbox_exporter_version }}.linux-{{ go_arch }}/blackbox_exporter" + delegate_to: localhost + check_mode: false + + - name: Propagate blackbox_exporter binaries + ansible.builtin.copy: + src: "/tmp/blackbox_exporter-{{ blackbox_exporter_version }}.linux-{{ go_arch }}/blackbox_exporter" + dest: "{{ blackbox_exporter_binary_install_dir }}/blackbox_exporter" + mode: 0755 + owner: root + group: root + notify: restart blackbox_exporter + when: not ansible_check_mode + +- name: Propagate locally distributed blackbox_exporter binary ansible.builtin.copy: - src: "/tmp/blackbox_exporter-{{ blackbox_exporter_version }}.linux-{{ go_arch_map[ansible_architecture] | default(ansible_architecture) }}/\ - blackbox_exporter" - dest: "/usr/local/bin/blackbox_exporter" - mode: 0750 + src: "{{ blackbox_exporter_binary_local_dir }}/blackbox_exporter" + dest: "{{ blackbox_exporter_binary_install_dir }}/blackbox_exporter" + mode: 0755 owner: root - group: "{{ blackbox_exporter_group }}" - when: not blackbox_exporter_skip_install - notify: - - restart blackbox exporter + group: root + when: + - blackbox_exporter_binary_local_dir | length > 0 + - not blackbox_exporter_skip_install + notify: restart blackbox_exporter - name: Install libcap on Debian systems ansible.builtin.package: diff --git a/roles/blackbox_exporter/tasks/preflight.yml b/roles/blackbox_exporter/tasks/preflight.yml index c3c7824fd..3deecc27c 100644 --- a/roles/blackbox_exporter/tasks/preflight.yml +++ b/roles/blackbox_exporter/tasks/preflight.yml @@ -24,3 +24,34 @@ ansible.builtin.assert: that: - "':' in blackbox_exporter_web_listen_address" + +- name: Discover latest version + ansible.builtin.set_fact: + blackbox_exporter_version: "{{ (lookup('url', 'https://api.github.com/repos/prometheus/blackbox_exporter/releases/latest', headers=_github_api_headers, + split_lines=False) | from_json).get('tag_name') | replace('v', '') }}" + run_once: true + until: blackbox_exporter_version is version('0.0.0', '>=') + retries: 10 + when: + - blackbox_exporter_version == "latest" + - blackbox_exporter_binary_local_dir | length == 0 + - not blackbox_exporter_skip_install + +- name: Get blackbox_exporter binary checksum + when: + - blackbox_exporter_binary_local_dir | length == 0 + - not blackbox_exporter_skip_install + block: + - name: Get checksum list from github + ansible.builtin.set_fact: + __blackbox_exporter_checksums: "{{ lookup('url', blackbox_exporter_checksums_url, headers=_github_api_headers, wantlist=True) | list }}" + run_once: true + until: __blackbox_exporter_checksums is search('linux-' + go_arch + '.tar.gz') + retries: 10 + + - name: "Get checksum for {{ go_arch }}" + ansible.builtin.set_fact: + __blackbox_exporter_checksum: "{{ item.split(' ')[0] }}" + with_items: "{{ __blackbox_exporter_checksums }}" + when: + - "('linux-' + go_arch + '.tar.gz') in item" diff --git a/roles/snmp_exporter/defaults/main.yml b/roles/snmp_exporter/defaults/main.yml index 221174f67..627c334dc 100644 --- a/roles/snmp_exporter/defaults/main.yml +++ b/roles/snmp_exporter/defaults/main.yml @@ -1,5 +1,6 @@ --- snmp_exporter_version: 0.23.0 +snmp_exporter_binary_local_dir: "" snmp_exporter_binary_url: "https://github.com/{{ _snmp_exporter_repo }}/releases/download/v{{ snmp_exporter_version }}/\ snmp_exporter-{{ snmp_exporter_version }}.linux-{{ go_arch_map[ansible_architecture] | default(ansible_architecture) }}.tar.gz" snmp_exporter_checksums_url: "https://github.com/{{ _snmp_exporter_repo }}/releases/download/v{{ snmp_exporter_version }}/sha256sums.txt" diff --git a/roles/snmp_exporter/meta/argument_specs.yml b/roles/snmp_exporter/meta/argument_specs.yml index 23e5287ad..3bf9dc211 100644 --- a/roles/snmp_exporter/meta/argument_specs.yml +++ b/roles/snmp_exporter/meta/argument_specs.yml @@ -9,12 +9,17 @@ argument_specs: - "Prometheus Community" options: snmp_exporter_version: - description: "SNMP exporter package version" + description: "SNMP exporter package version. Also accepts latest as parameter." default: "0.23.0" snmp_exporter_skip_install: description: "SNMP exporter installation tasks gets skipped when set to true." type: bool default: false + snmp_exporter_binary_local_dir: + description: + - "Enables the use of local packages instead of those distributed on github." + - "The parameter masnmp set to a directory where the C(snmp_exporter) binary is stored on the host where ansible is run." + - "This overrides the I(snmp_exporter_version) parameter" snmp_exporter_binary_url: description: "URL of the snmp exporter binaries .tar.gz file" default: "https://github.com/{{ _snmp_exporter_repo }}/releases/download/v{{ snmp_exporter_version }}/snmp_exporter-{{ snmp_exporter_version }}.linux-{{ go_arch_map[ansible_architecture] | default(ansible_architecture) }}.tar.gz" diff --git a/roles/snmp_exporter/tasks/install.yml b/roles/snmp_exporter/tasks/install.yml index a67690484..ecf03d795 100644 --- a/roles/snmp_exporter/tasks/install.yml +++ b/roles/snmp_exporter/tasks/install.yml @@ -1,37 +1,54 @@ --- -- name: Download snmp_exporter binary to local folder - become: false - ansible.builtin.get_url: - url: "{{ snmp_exporter_binary_url }}" - dest: "/tmp" - checksum: "sha256:{{ snmp_exporter_checksum }}" - mode: 0644 - register: _download_binary - until: _download_binary is success - retries: 5 - delay: 2 - delegate_to: localhost - check_mode: false - when: not snmp_exporter_skip_install +- name: Get binary + when: + - snmp_exporter_binary_local_dir | length == 0 + - not snmp_exporter_skip_install + block: -- name: Unpack snmp_exporter binary - become: false - ansible.builtin.unarchive: - src: "/tmp/snmp_exporter-{{ snmp_exporter_version }}.linux-{{ go_arch_map[ansible_architecture] | default(ansible_architecture) }}.tar.gz" - dest: "/tmp" - creates: "/tmp/snmp_exporter-{{ snmp_exporter_version }}.linux-{{ go_arch_map[ansible_architecture] | default(ansible_architecture) }}/snmp_exporter" - delegate_to: localhost - check_mode: false - when: not snmp_exporter_skip_install + - name: Download snmp_exporter binary to local folder + become: false + ansible.builtin.get_url: + url: "{{ snmp_exporter_binary_url }}" + dest: "/tmp/snmp_exporter-{{ snmp_exporter_version }}.linux-{{ go_arch }}.tar.gz" + checksum: "sha256:{{ __snmp_exporter_checksum }}" + mode: '0644' + register: _download_binary + until: _download_binary is succeeded + retries: 5 + delay: 2 + delegate_to: localhost + check_mode: false -- name: Propagate SNMP Exporter binaries + - name: Unpack snmp_exporter binary + become: false + ansible.builtin.unarchive: + src: "/tmp/snmp_exporter-{{ snmp_exporter_version }}.linux-{{ go_arch }}.tar.gz" + dest: "/tmp" + creates: "/tmp/snmp_exporter-{{ snmp_exporter_version }}.linux-{{ go_arch }}/snmp_exporter" + delegate_to: localhost + check_mode: false + + - name: Propagate snmp_exporter binaries + ansible.builtin.copy: + src: "/tmp/snmp_exporter-{{ snmp_exporter_version }}.linux-{{ go_arch }}/snmp_exporter" + dest: "{{ snmp_exporter_binary_install_dir }}/snmp_exporter" + mode: 0755 + owner: root + group: root + notify: restart snmp_exporter + when: not ansible_check_mode + +- name: Propagate locally distributed snmp_exporter binary ansible.builtin.copy: - src: "/tmp/snmp_exporter-{{ snmp_exporter_version }}.linux-{{ go_arch_map[ansible_architecture] | default(ansible_architecture) }}/snmp_exporter" - dest: "/usr/local/bin/snmp_exporter" + src: "{{ snmp_exporter_binary_local_dir }}/snmp_exporter" + dest: "{{ snmp_exporter_binary_install_dir }}/snmp_exporter" mode: 0755 - when: not snmp_exporter_skip_install - notify: - - restart snmp exporter + owner: root + group: root + when: + - snmp_exporter_binary_local_dir | length > 0 + - not snmp_exporter_skip_install + notify: restart snmp_exporter - name: Create configuration directory ansible.builtin.file: diff --git a/roles/snmp_exporter/tasks/preflight.yml b/roles/snmp_exporter/tasks/preflight.yml index f6ffdeac9..d72310c32 100644 --- a/roles/snmp_exporter/tasks/preflight.yml +++ b/roles/snmp_exporter/tasks/preflight.yml @@ -1,9 +1,31 @@ --- -- name: "Get checksum for snmp exporter" +- name: Discover latest version ansible.builtin.set_fact: - snmp_exporter_checksum: "{{ item.split(' ')[0] }}" - with_items: - - "{{ lookup('url', snmp_exporter_checksums_url, headers=_github_api_headers, wantlist=True) | list }}" + snmp_exporter_version: "{{ (lookup('url', 'https://api.github.com/repos/prometheus/snmp_exporter/releases/latest', headers=_github_api_headers, + split_lines=False) | from_json).get('tag_name') | replace('v', '') }}" + run_once: true + until: snmp_exporter_version is version('0.0.0', '>=') + retries: 10 when: - - "('linux-' + (go_arch_map[ansible_architecture] | default(ansible_architecture)) + '.tar.gz') in item" + - snmp_exporter_version == "latest" + - snmp_exporter_binary_local_dir | length == 0 - not snmp_exporter_skip_install + +- name: Get snmp_exporter binary checksum + when: + - snmp_exporter_binary_local_dir | length == 0 + - not snmp_exporter_skip_install + block: + - name: Get checksum list from github + ansible.builtin.set_fact: + __snmp_exporter_checksums: "{{ lookup('url', snmp_exporter_checksums_url, headers=_github_api_headers, wantlist=True) | list }}" + run_once: true + until: __snmp_exporter_checksums is search('linux-' + go_arch + '.tar.gz') + retries: 10 + + - name: "Get checksum for {{ go_arch }}" + ansible.builtin.set_fact: + __snmp_exporter_checksum: "{{ item.split(' ')[0] }}" + with_items: "{{ __snmp_exporter_checksums }}" + when: + - "('linux-' + go_arch + '.tar.gz') in item"