diff --git a/README.md b/README.md index 3edfbf7..7bd4f5b 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ -# role_modele +# role_hcio -Modèle \ No newline at end of file +Deploy checks sent to a [healthchecks.io](https://healthchecks.io/) server. diff --git a/defaults/main.yml b/defaults/main.yml new file mode 100644 index 0000000..c73ab1d --- /dev/null +++ b/defaults/main.yml @@ -0,0 +1,24 @@ +--- +# defaults file for hcio + +# Path to store checks UUID +hcio_local_facts_file: /etc/ansible/facts.d/hcio.fact + +# Pat to store scripts +hcio_path: /srv/healthchecksio + +# Informations about hcio server +hcio_url: "" +hcio_api_key: "" + +# Add prefix on slug +hcio_slug_prefix: "{{ inventory_hostname | replace('.', '_') }}-" + +# Define checks +hcio_checks: [] +# Example : +# - name: "{{ inventory_hostname }}" +# tags: "{{ group_names }}" +# timeout: 300 +# channels: "{{ hcio_host_channels }}" +# target: host diff --git a/handlers/main.yml b/handlers/main.yml new file mode 100644 index 0000000..61574c4 --- /dev/null +++ b/handlers/main.yml @@ -0,0 +1,35 @@ +--- +# handlers file for hcio + +- name: Write UUID in local facts + community.general.ini_file: + path: "{{ hcio_local_facts_file }}" + section: role_hcio + option: "{{ item.json.slug | replace(hcio_slug_prefix, '') }}" + value: "{{ item.json.ping_url.split('/') | last }}" + create: false + when: item.changed + become: true + loop: "{{ created.results }}" + loop_control: + label: "{{ item.get('json', {}).get('slug', '') }}" + +- name: Reload local facts + ansible.builtin.setup: + filter: ansible_local + +- name: Enable timer + ansible.builtin.systemd: + name: "{{ filename }}.timer" + state: started + enabled: true + daemon_reload: true + become: true + +- name: Start service + ansible.builtin.systemd: + name: "{{ filename }}.service" + state: started + enabled: false + daemon_reload: true + become: true diff --git a/meta/main.yml b/meta/main.yml index c58bebf..a272c14 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -1,7 +1,7 @@ galaxy_info: namespace: ykn author: pulsar89.5 - description: Rôle modèle + description: Deploy checks sent to a healthchecks.io server license: GPL-3.0-or-later diff --git a/tasks/checks.yml b/tasks/checks.yml new file mode 100644 index 0000000..4230768 --- /dev/null +++ b/tasks/checks.yml @@ -0,0 +1,135 @@ +--- +# tasks file for hcio + +- name: Create checks on the server + ansible.builtin.uri: + status_code: [200, 201] + method: POST + url: "{{ hcio_url }}/api/v3/checks/" + headers: + X-Api-Key: "{{ hcio_api_key }}" + body_format: json + body: > + { + "name": "{{ item.name }}", + "slug": "{{ hcio_slug_prefix }}{{ item.slug }}", + "tags": "{{ item.tags | join(' ') }}", + "timeout": {{ timeout }}, + "grace": {{ item.grace if item.grace is defined else grace }}, + "channels": "{{ channels }}", + "unique": ["name"] + } + when: uuid | length <= 0 + changed_when: true + register: created + loop: "{{ hcio_checks }}" + loop_control: + label: "{{ item.name }}" + notify: + - Write UUID in local facts + - Reload local facts + vars: + timeout: "{{ (item.timeout | int) + 30 }}" + grace: "{{ (item.timeout | int) * 3 }}" + channels: "{{ item.channels | join(',') }}" + uuid: "{{ ansible_local.get('chaos', {}).get('role_hcio', {}).get(item.slug, {}) }}" + +- name: Flush handlers + ansible.builtin.meta: flush_handlers + +- name: Update checks on the server + ansible.builtin.uri: + status_code: [200, 201] + method: POST + url: "{{ hcio_url }}/api/v3/checks/{{ uuid }}" + headers: + X-Api-Key: "{{ hcio_api_key }}" + body_format: json + body: > + { + "slug": "{{ hcio_slug_prefix }}{{ item.slug }}", + "tags": "{{ item.tags | join(' ') }}", + "timeout": {{ timeout }}, + "grace": {{ item.grace if item.grace is defined else grace }}, + "channels": "{{ channels }}", + } + when: uuid | length > 0 + loop: "{{ hcio_checks }}" + loop_control: + label: "{{ item.name }}" + vars: + timeout: "{{ (item.timeout | int) + 30 }}" + grace: "{{ (item.timeout | int) * 3 }}" + channels: "{{ item.channels | join(',') }}" + uuid: "{{ ansible_local.get('chaos', {}).get('role_hcio', {}).get(item.slug, {}) }}" + +- name: Deploy scripts from this role + ansible.builtin.copy: + src: "{{ item }}" + dest: "{{ hcio_path }}/{{ filename }}" + owner: root + group: root + mode: u=rwx,g=rx,o=rx + become: true + loop: "{{ lookup('ansible.builtin.fileglob', path + '/*.j2', wantlist=True) }}" + vars: + path: "{{ role_path }}/templates/scripts" + filename: "{{ item | basename | replace('.j2', '') }}" + +- name: Deploy scripts from playbook + ansible.builtin.copy: + src: "{{ item }}" + dest: "{{ hcio_path }}/{{ filename }}" + owner: root + group: root + mode: u=rwx,g=rx,o=rx + become: true + loop: "{{ lookup('ansible.builtin.fileglob', path + '/*.j2', wantlist=True) }}" + vars: + path: "{{ playbook_dir }}/templates/role_hcio" + filename: "{{ item | basename | replace('.j2', '') }}" + +- name: Deploy checks on the instance + ansible.builtin.template: + owner: root + group: root + mode: u=rw,g=r,o=r + src: service.j2 + dest: /etc/systemd/system/{{ filename }}.service + when: item.cmd is defined + become: true + loop: "{{ hcio_checks }}" + loop_control: + label: "{{ item.name }}" + vars: + filename: "hcio@{{ item.slug }}" + uuid: "{{ ansible_local.get('chaos', {}).get('role_hcio', {}).get(item.slug, {}) }}" + +- name: Deploy schedules on the instance + ansible.builtin.template: + owner: root + group: root + mode: u=rw,g=r,o=r + src: timer.j2 + dest: /etc/systemd/system/{{ filename }}.timer + when: item.cmd is defined + become: true + loop: "{{ hcio_checks }}" + loop_control: + label: "{{ item.name }}" + vars: + filename: "hcio@{{ item.slug }}" + +- name: Enable schedules + ansible.builtin.systemd: + enabled: true + daemon_reload: true + state: started + name: "{{ filename }}.timer" + when: item.cmd is defined + become: true + loop: "{{ hcio_checks }}" + loop_control: + label: "{{ item.name }}" + vars: + filename: "hcio@{{ item.slug }}" diff --git a/tasks/main.yml b/tasks/main.yml new file mode 100644 index 0000000..fe1559a --- /dev/null +++ b/tasks/main.yml @@ -0,0 +1,29 @@ +--- +# tasks file for hcio + +- name: Install prerequisites + ansible.builtin.apt: + name: "{{ hcio_prerequisites }}" + become: true + +- name: Create directory to store scripts + ansible.builtin.file: + path: "{{ hcio_path }}" + state: directory + owner: root + group: root + mode: u=rwX,g=rX,o= + become: true + +- name: Build the checks list + ansible.builtin.set_fact: + hcio_checks: "{{ hcio_checks + specific }}" + when: specific | length > 0 + loop: "{{ lookup('ansible.builtin.varnames', '^hcio_checks_.+', wantlist=True) }}" + vars: + specific: "{{ lookup('ansible.builtin.vars', item, default='') }}" + +- name: Import checks deployment tasks + ansible.builtin.include_tasks: + file: checks.yml + when: hcio_checks | length > 0 diff --git a/templates/scripts/disk.bash.j2 b/templates/scripts/disk.bash.j2 new file mode 100644 index 0000000..2ecc349 --- /dev/null +++ b/templates/scripts/disk.bash.j2 @@ -0,0 +1,12 @@ +#!/bin/bash +# {{ ansible_managed }} + +# Get disk usage in percent +pct=$(df --output=pcent $1 | tail -n 1 | tr -d '% ') + +# Fail if disk is used more than limit +if [ $pct -gt $2 ]; then + /usr/bin/curl -s --retry 5 -o /dev/null "${3}/fail" +else + /usr/bin/curl -s --retry 5 -o /dev/null "${3}" +fi diff --git a/templates/service.j2 b/templates/service.j2 new file mode 100644 index 0000000..6c5a338 --- /dev/null +++ b/templates/service.j2 @@ -0,0 +1,12 @@ +# {{ ansible_managed }} + +[Unit] +Description={{ item.name }} +After=network.target + +[Service] +Type=oneshot +ExecStart={{ item.cmd }} "{{ hcio_url }}/ping/{{ uuid }}" + +[Install] +WantedBy=multi-user.target diff --git a/templates/service.j2.backup b/templates/service.j2.backup new file mode 100644 index 0000000..844b946 --- /dev/null +++ b/templates/service.j2.backup @@ -0,0 +1,18 @@ +# {{ ansible_managed }} + +[Unit] +Description={{ item.name }} +After=network.target + +[Service] +Type=oneshot +{% if item.cmd is defined %} +ExecStart={{ item.cmd }} && /usr/bin/curl -s --retry 5 -o /dev/null {{ hcio_url }}/ping/{{ uuid }} +{% elif item.script is defined %} +ExecStart={{ hcio_path }}/scripts/{{ item.script | basename }} "{{ hcio_url }}/ping/{{ uuid }}" +{% else %} +ExecStart=/usr/bin/curl -s --retry 5 -o /dev/null {{ hcio_url }}/ping/{{ uuid }} +{% endif %} + +[Install] +WantedBy=multi-user.target diff --git a/templates/timer.j2 b/templates/timer.j2 new file mode 100644 index 0000000..2c9fe1a --- /dev/null +++ b/templates/timer.j2 @@ -0,0 +1,12 @@ +# {{ ansible_managed }} + +[Unit] +Description={{ item.name }} + +[Timer] +OnBootSec={{ (item.timeout | int) - 10 }}second +OnUnitActiveSec={{ (item.timeout | int) - 10 }}second +Persistent=true + +[Install] +WantedBy=timers.target diff --git a/vars/main.yml b/vars/main.yml new file mode 100644 index 0000000..be164c6 --- /dev/null +++ b/vars/main.yml @@ -0,0 +1,5 @@ +--- +# vars file for hcio + +hcio_prerequisites: + - curl