From 8916f8fa2167abad24cfdd2a9e305160d83a6958 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Duchaussois?= Date: Wed, 28 Apr 2021 16:49:16 +0200 Subject: feature: add sensor configuration --- .github/workflows/pr.yml | 11 +- README.md | 17 +++ defaults/main.yml | 5 + molecule/features/INSTALL.rst | 15 ++ molecule/features/converge.yml | 7 + molecule/features/host_vars/instance-features.yml | 11 ++ molecule/features/molecule.yml | 21 +++ molecule/features/prepare.yml | 19 +++ molecule/features/verify.yml | 40 ++++++ tasks/config.yml | 162 ++++++++++++++++++++++ tasks/main.yml | 4 + templates/health_template.j2 | 6 + templates/netdata_alarm.conf.j2 | 21 +++ 13 files changed, 338 insertions(+), 1 deletion(-) create mode 100644 molecule/features/INSTALL.rst create mode 100644 molecule/features/converge.yml create mode 100644 molecule/features/host_vars/instance-features.yml create mode 100644 molecule/features/molecule.yml create mode 100644 molecule/features/prepare.yml create mode 100644 molecule/features/verify.yml create mode 100644 tasks/config.yml create mode 100644 templates/health_template.j2 create mode 100644 templates/netdata_alarm.conf.j2 diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index dfd5489..36a66a1 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -8,7 +8,7 @@ on: branches: - master jobs: - build: + molecule_default: runs-on: ubuntu-latest strategy: max-parallel: 4 @@ -31,3 +31,12 @@ jobs: env: MOLECULE_OS: ${{ matrix.molecule-os }} MOLECULE_NETDATA_INSTALLER: ${{ matrix.netdata-installer }} + molecule_features: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + path: "${{ github.repository }}" + - uses: gofrolist/molecule-action@v2 + with: + molecule_args: --scenario-name features diff --git a/README.md b/README.md index d4a2e18..e43c42b 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,23 @@ Role Variables See [defaults/main.yml] +* `netdata_extra_config`: An array of application configurations. Defaults to `[]` + * `name`: the name of the specified collector + * `specific_task_file`: a task file to be included. + * `apt_dependencies`: an array of package dependencies + * `pip_dependencies`: an array of pip dependencies to be installed + * `extra_groups`: an array of groups to add netdata user to + * `read_files`: an array of file path to which netdata user should be granted access + * `collector_type`: `python`, `node`, `go` or `charts` + * `replace`: when a sensor is changed from one type to another allow ro remove the old configuration + * `config`: the content of the configuration file as yaml to be put in `$type.d` config + * `health_config`: the templates as in netdata acceptation for this collector, an array of templates configuration + * `name`: the template name + * `definition`: a list of string defining the template (like 'on: apache.requests') +* `netdata_alarms_overrides`: an array of override for default netdata templates + * `name`: friendly name of the override (filesystem compatible) + * `override`: the content of the override + Dependencies ------------ diff --git a/defaults/main.yml b/defaults/main.yml index 12c5fe6..3026012 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -26,3 +26,8 @@ netdata_streaming_configuration: netdata_alarm_notify_configs: {} # Define a custom_sender function to be used in alarm configuration netdata_custom_sender_function: "" +netdata_extra_config: [] +netdata_alarms_overrides: [] + +netdata_pip_package: + Ubuntu20.04: python3-pip diff --git a/molecule/features/INSTALL.rst b/molecule/features/INSTALL.rst new file mode 100644 index 0000000..c615318 --- /dev/null +++ b/molecule/features/INSTALL.rst @@ -0,0 +1,15 @@ +******* +Delegated driver installation guide +******* + +Requirements +============ + +This driver is delegated to the developer. Up to the developer to implement +requirements. + +Install +======= + +This driver is delegated to the developer. Up to the developer to implement +requirements. diff --git a/molecule/features/converge.yml b/molecule/features/converge.yml new file mode 100644 index 0000000..37f6dea --- /dev/null +++ b/molecule/features/converge.yml @@ -0,0 +1,7 @@ +--- +- name: Converge + hosts: all + tasks: + - name: "Include netdata-straight" + include_role: + name: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" diff --git a/molecule/features/host_vars/instance-features.yml b/molecule/features/host_vars/instance-features.yml new file mode 100644 index 0000000..fe33d25 --- /dev/null +++ b/molecule/features/host_vars/instance-features.yml @@ -0,0 +1,11 @@ +netdata_installer: kickstart-static64 +netdata_extra_config: + - name: test user + extra_groups: + - fakegroup + read_files: + - /etc/fakefile.conf + pip_dependencies: + - test-pip-install + apt_dependencies: + - hxtools diff --git a/molecule/features/molecule.yml b/molecule/features/molecule.yml new file mode 100644 index 0000000..ae3d948 --- /dev/null +++ b/molecule/features/molecule.yml @@ -0,0 +1,21 @@ +--- +dependency: + name: galaxy +driver: + name: docker +platforms: + - name: instance-features + image: jrei/systemd-ubuntu:20.04 + privileged: true + command: /lib/systemd/systemd + tmpfs: + - /run + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro +provisioner: + name: ansible + inventory: + links: + host_vars: host_vars/ +verifier: + name: ansible diff --git a/molecule/features/prepare.yml b/molecule/features/prepare.yml new file mode 100644 index 0000000..b4e8439 --- /dev/null +++ b/molecule/features/prepare.yml @@ -0,0 +1,19 @@ +- name: Prepare + hosts: all + tasks: + - name: Update apt cache + apt: + update_cache: yes + become: true + when: ansible_os_family == 'Debian' + - name: Create fakegroup + group: + name: fakegroup + state: present + - name: Create fake conf file + copy: + content: "Test file" + dest: /etc/fakefile.conf + owner: root + group: root + mode: 0600 diff --git a/molecule/features/verify.yml b/molecule/features/verify.yml new file mode 100644 index 0000000..9f64471 --- /dev/null +++ b/molecule/features/verify.yml @@ -0,0 +1,40 @@ +--- +# This is an example playbook to execute Ansible tests. +- name: Verify + hosts: all + gather_facts: false + tasks: + - name: Get netdata groups + command: id -Gzn + register: netdata_groups_st + become: true + become_user: netdata + changed_when: false + + - name: Check file access + stat: + path: /etc/fakefile.conf + become: yes + become_user: netdata + register: netdata_stat_st + + - name: Check pip package + command: test-pip-install + become: yes + become_user: netdata + changed_when: false + + - name: Check apt package + command: rot13 + args: + stdin: test + changed_when: false + + - name: Asserts config was applied + assert: + that: + - "'fakegroup' in group_array" + - netdata_can_read + vars: + group_array: "{{ netdata_groups_st.stdout.split('\0') | reject('eq','') | list }}" + netdata_can_read: "{{ netdata_stat_st.stat.readable }}" diff --git a/tasks/config.yml b/tasks/config.yml new file mode 100644 index 0000000..4ada6e6 --- /dev/null +++ b/tasks/config.yml @@ -0,0 +1,162 @@ +- name: Run specific tasks + include_tasks: "{{ item.specific_task_file }}" + when: item.specific_task_file is defined + loop: "{{ netdata_extra_config }}" + +- name: Configure plugins apt dependencies + apt: + name: "{{ netdata_plugins_apt }}" + state: present + vars: + netdata_plugins_apt: "{{ netdata_extra_config | map(attribute='apt_dependencies') | + reject('undefined') | list | flatten | unique }}" + register: netdata_plugins_apt_deps_st + until: netdata_plugins_apt_deps_st is succeeded + +- name: Get list of pip dependencies + set_fact: + netdata_plugins_pip: "{{ netdata_extra_config | map(attribute='pip_dependencies') | + reject('undefined') | list | flatten | unique }}" + +- name: Install pip for python dependencies + apt: + name: "{{ python_package }}" + state: present + when: + - netdata_plugins_pip|length > 0 + - ansible_os_family == 'Debian' + vars: + python_package: "{{ netdata_pip_package[ansible_distribution ~ ansible_distribution_version] | default('python-pip') }}" + register: netdata_pip_install + until: netdata_pip_install is succeeded + +- name: Configure plugins pip dependencies + pip: + name: "{{ netdata_plugins_pip }}" + state: present + when: netdata_plugins_pip|length > 0 + register: netdata_plugins_pip_deps_st + until: netdata_plugins_pip_deps_st is succeeded + +- name: Add netdata to extra groups + user: + name: netdata + groups: "{{ netdata_plugins_groups }}" + append: yes + notify: restart netdata + vars: + netdata_plugins_groups: "{{ netdata_extra_config | map(attribute='extra_groups') | + reject('undefined') | list | flatten | unique }}" + +- name: Get list of files to grant read on + set_fact: + netdata_plugins_files: "{{ netdata_extra_config | map(attribute='read_files') | + reject('undefined') | list | flatten | unique }}" + +- name: Install acl if files need to be granted access + apt: + name: acl + state: present + when: netdata_plugins_files|length > 0 + +- name: Grant read acces to files + acl: + path: "{{ item }}" + entity: netdata + etype: user + permissions: r + state: present + notify: restart netdata + loop: "{{ netdata_plugins_files }}" + +- name: Configure plugins + copy: + dest: "{{ netdata_collector_conf_dir }}/{{ collector.name }}.conf" + content: "{{ content[collector.format | default('yaml')] }}" + mode: 0640 + owner: netdata + when: collector.config is defined + notify: restart netdata + loop: "{{ netdata_extra_config }}" + loop_control: + loop_var: collector + label: "{{ collector.name }}" + vars: + netdata_collector_conf_dir: "/etc/netdata/{{ collector.type }}.d" + bash_content_tmp: "{{ collector.config.items() | sort | list | map('join','=') | list }}" + bash_content: "{{ bash_content_tmp | map('regex_replace','(.*)=(.*)',collector.name ~ '_\\1=\\2') | join('\n') }}" + yaml_content: "{{ collector.config | to_nice_yaml }}" + json_content: "{{ collector.config | to_nice_json }}" + content: + bash: "{{ bash_content ~ '\n' }}" + json: "{{ json_content }}" + yaml: "{{ yaml_content }}" + no_log: "{{ collector.no_log | default(false) }}" + +- name: Remove old config + file: + path: "{{ netdata_old_collector_conf_dir }}/{{ collector.name }}.conf" + state: absent + when: collector.replace is defined + notify: restart netdata + loop: "{{ netdata_extra_config }}" + loop_control: + loop_var: collector + label: "{{ collector.name }}" + vars: + netdata_old_collector_conf_dir: "/etc/netdata/{{ collector.replace }}.d" + +- name: Configure chart + copy: + dest: "{{ netdata_collector_chart_dir }}" + src: "{{ collector.chart_name }}.chart.sh" + mode: 0755 + owner: netdata + when: collector.chart_name is defined + notify: restart netdata + loop: "{{ netdata_extra_config }}" + loop_control: + loop_var: collector + label: "{{ collector.name }}" + vars: + netdata_collector_chart_dir: "/usr/libexec/netdata/charts.d/" + +- name: Configure plugins health + template: + dest: "{{ netdata_health_conf_dir }}/{{ collector.name }}.conf" + src: health_template.j2 + mode: 0640 + owner: netdata + when: collector.health_config is defined + notify: restart netdata # a reload would be enough + loop: "{{ netdata_extra_config }}" + loop_control: + loop_var: collector + label: "{{ collector.name }}" + +- name: Configure overrides + copy: + dest: "{{ netdata_health_conf_dir }}/{{ override.name }}.conf" + content: | + # {{ override.name }} + {{ override.override }} + mode: 0640 + owner: netdata + notify: reload netdata + loop: "{{ netdata_alarms_overrides }}" + loop_control: + loop_var: override + label: "{{ override.name }}" + +- name: Configure alarm + template: + dest: "{{ netdata_health_conf_dir }}/{{ collector.name }}.conf" + src: "netdata_alarm.conf.j2" + mode: 0755 + owner: netdata + when: collector.alarm_config is defined + notify: restart netdata + loop: "{{ netdata_extra_config }}" + loop_control: + loop_var: collector + label: "{{ collector.name }}" diff --git a/tasks/main.yml b/tasks/main.yml index ca849a3..f05eff4 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -65,3 +65,7 @@ - netdata_alarm_notify_configs is defined - netdata_alarm_notify_configs | count > 0 notify: restart netdata + +- name: Configure netdata sensors + include_tasks: config.yml + when: (netdata_extra_config|length > 0) or (netdata_alarms_overrides|length > 0) diff --git a/templates/health_template.j2 b/templates/health_template.j2 new file mode 100644 index 0000000..2e67b96 --- /dev/null +++ b/templates/health_template.j2 @@ -0,0 +1,6 @@ +{% for template in collector.health_config %} +template = {{ template.name }} +{% for config in template.definition %} +{{ config }} +{% endfor %} +{% endfor %} diff --git a/templates/netdata_alarm.conf.j2 b/templates/netdata_alarm.conf.j2 new file mode 100644 index 0000000..c689a95 --- /dev/null +++ b/templates/netdata_alarm.conf.j2 @@ -0,0 +1,21 @@ +{% for alarm in collector.alarm_config %} +{% if alarm.template is defined -%} +template: {{ alarm.template }} +families: {{ alarm.families | default("*") }} +{% else %} + alarm: {{ alarm.alarm | default( collector.name ) }} +{% endif %} + on: {{ alarm.on_what }} + os: {{ alarm.os | default("*") }} + hosts: {{ alarm.os | default("*") }} + lookup: {{ alarm.lookup }} +{% if alarm.calc is defined %} + calc: {{ alarm.calc }} +{% endif %} + every: {{ alarm.every | default("1m") }} + warn: {{ alarm.warn | default("$status == $WARNING") }} + crit: {{ alarm.crit | default("$status == $CRITICAL") }} + delay: {{ alarm.delay | default("up 0 down 0 multiplier 1.0 max 0") }} + to: {{ alarm.to | default("silent") }} + +{% endfor %} -- cgit v1.2.3