Merge pull request #30 from corvus-migratorius/add-curl-scheduled

Add curl scheduled
This commit is contained in:
Fogucoco
2025-12-16 13:36:56 +03:00
committed by GitHub
15 changed files with 307 additions and 1 deletions

View File

@@ -7,6 +7,7 @@
- [alertmanager](roles/alertmanager/README.md)
- [borgmatic](roles/borgmatic/README.md)
- [curl_scheduled](roles/curl_scheduled/README.md)
- [dnsmasq](roles/dnsmasq/README.md)
- [grafana](roles/grafana/README.md)
- [ipmi_exporter](roles/ipmi_exporter/README.md)

View File

@@ -1,7 +1,7 @@
---
namespace: genlab
name: common
version: 0.11.0
version: 0.12.0
readme: README.md
authors:
- Alexander Gorelyshev (corvus-migratorius@proton.me)

2
roles/curl_scheduled/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
.vscode
.idea

View File

@@ -0,0 +1,41 @@
curl-scheduled
=========
Configure curl to run on schedule by deploying a systemd service + timer. Useful for sending heartbeats.
Requirements
------------
None
Role Variables
--------------
- `args`: arguments to the curl command
- `url`: address to be accessed by curl
- `schedule`: string compatible with systemd timer `OnSchedule` option (default: `minutely`)
Dependencies
------------
None
Example Playbook
----------------
See `molecule/default/converge.yml`.
License
-------
BSD
Author Information
------------------
msayganova@genlab.llc
corvus-migratorius@proton.me

View File

@@ -0,0 +1,4 @@
---
curl_scheduled_curl_cmd: "/usr/bin/curl"
curl_scheduled_curl_args: "-fsS -m 10"
curl_scheduled_schedule: "minutely"

View File

@@ -0,0 +1 @@
---

View File

@@ -0,0 +1,17 @@
---
galaxy_info:
role_name: curl_scheduled
namespace: genlab
author: "Alexander Gorelyshev"
company: "Genlab, LLC"
description: ""
license: "MIT"
min_ansible_version: "2.1"
platforms:
- name: "Ubuntu"
versions: ["focal", "jammy", "noble"]
galaxy_tags: []
dependencies: []

View File

@@ -0,0 +1,45 @@
---
- name: Converge
hosts: all
pre_tasks:
- name: "Create test directory"
ansible.builtin.file:
path: "/test"
state: directory
mode: "0664"
- name: "Create a test file"
ansible.builtin.lineinfile:
path: "/test/index.html"
create: true
mode: "0664"
line: "OK"
- name: "Simulate remote HTTP server(s) directly on localhost"
changed_when: false
async: 1
poll: 0
args:
chdir: "/test"
loop:
- 8080
- 8081
- 8082
ansible.builtin.shell:
cmd: nohup python3 -m http.server {{ item }} </dev/null >/dev/null 2>&1 &
executable: /bin/bash
roles:
- role: genlab.common.curl_scheduled
services:
- label: "localhost-test-zero"
url: "http://127.0.0.1:8080"
schedule: minutely
- label: "localhost-test-one"
url: "http://127.0.0.1:8081"
schedule: hourly
- label: "localhost-test-chained-curl"
curl_cmd: '/usr/bin/curl "http://127.0.0.1:8081" && /usr/bin/curl'
url: "http://127.0.0.1:8082"
schedule: minutely

View File

@@ -0,0 +1,27 @@
---
dependency:
name: galaxy
driver:
name: docker
platforms:
- name: ubuntu
image: geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2404}-ansible:latest
pre_build_image: true
command: ${MOLECULE_DOCKER_COMMAND:-""}
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
cgroupns_mode: host
privileged: true
provisioner:
name: ansible
verifier:
name: ansible
lint: |
set -e
yamllint .
ansible-lint .

View File

@@ -0,0 +1,81 @@
---
- name: Verify
hosts: all
gather_facts: false
tasks:
# Verify the systemd timers
- name: "Check the timer status - localhost-test-zero"
register: curl_scheduled_timer_zero
ansible.builtin.systemd:
name: "curl-localhost-test-zero.timer"
- name: "Assert that the localhost-test-zero timer is running"
ansible.builtin.assert:
that:
- curl_scheduled_timer_zero.status.ActiveState == "active"
success_msg: "Timer is running"
fail_msg: "Unexpected timer state: '{{ curl_scheduled_timer_zero.status.ActiveState }}'"
- name: "Check the timer status - localhost-test-one"
register: curl_scheduled_timer_one
ansible.builtin.systemd:
name: "curl-localhost-test-one.timer"
- name: "Assert that the localhost-test-one timer is running"
ansible.builtin.assert:
that:
- curl_scheduled_timer_one.status.ActiveState == "active"
success_msg: "Timer is running"
fail_msg: "Unexpected timer state: '{{ curl_scheduled_timer_one.status.ActiveState }}'"
- name: "Check the timer status - localhost-test-chained-curl"
register: curl_scheduled_timer_chained_curl
ansible.builtin.systemd:
name: "curl-localhost-test-chained-curl.timer"
- name: "Assert that the localhost-test-chained-curl timer is running"
ansible.builtin.assert:
that:
- curl_scheduled_timer_chained_curl.status.ActiveState == "active"
success_msg: "Timer is running"
fail_msg: "Unexpected timer state: '{{ curl_scheduled_timer_chained_curl.status.ActiveState }}'"
## Verify the systemd services
- name: "Check the service status - zero"
register: curl_scheduled_service_zero
ansible.builtin.systemd:
name: "curl-localhost-test-zero.service"
- name: "Assert that the localhost-test-zero service exited with a 0/SUCCESS status"
ansible.builtin.assert:
that:
- 'curl_scheduled_service_zero.status.ExecMainStatus == "0"'
success_msg: "Service has exited with a 0/SUCCESS status"
fail_msg: "Unexpected service status code: '{{ curl_scheduled_service_zero.status.ExecMainStatus }}'"
- name: "Check the service status - one"
register: curl_scheduled_service_one
ansible.builtin.systemd:
name: "curl-localhost-test-one.service"
- name: "Assert that the localhost-test-one service exited with a 0/SUCCESS status"
ansible.builtin.assert:
that:
- 'curl_scheduled_service_one.status.ExecMainStatus == "0"'
success_msg: "Service has exited with a 0/SUCCESS status"
fail_msg: "Unexpected service status code: '{{ curl_scheduled_service_one.status.ExecMainStatus }}'"
- name: "Check the service status - localhost-test-chained-curl"
register: curl_scheduled_service_chained_curl
ansible.builtin.systemd:
name: "curl-localhost-test-chained-curl.service"
- name: "Assert that the localhost-test-chained-curl service exited with a 0/SUCCESS status"
ansible.builtin.assert:
that:
- 'curl_scheduled_service_chained_curl.status.ExecMainStatus == "0"'
success_msg: "Service has exited with a 0/SUCCESS status"
fail_msg: "Unexpected service status code: '{{ curl_scheduled_service_chained_curl.status.ExecMainStatus }}'"

View File

@@ -0,0 +1,33 @@
---
- name: "Deploy-Service | Create systemd service file: '{{ job.label }}'"
vars:
label: "{{ job.label }}"
url: "{{ job.url }}"
curl_cmd: "{{ job.curl_cmd | default(curl_scheduled_curl_cmd) }}"
curl_args: "{{ job.curl_args | default(curl_scheduled_curl_args) }}"
register: curl_scheduled_service
ansible.builtin.template:
src: "placeholder.service"
dest: "/etc/systemd/system/curl-{{ job.label }}.service"
mode: "0660"
validate: systemd-analyze verify %s
- name: "Deploy-Service | Create systemd timer file: '{{ job.label }}'"
vars:
label: "{{ job.label }}"
schedule: "{{ job.schedule | default(curl_scheduled_schedule) }}"
register: curl_scheduled_timer
ansible.builtin.template:
src: "placeholder.timer"
dest: "/etc/systemd/system/curl-{{ job.label }}.timer"
mode: "0660"
validate: systemd-analyze verify %s
- name: "Deploy-Service | Enable and start the timer: '{{ job.label }}'" # noqa: no-handler
become: true
when: curl_scheduled_service.changed or curl_scheduled_timer.changed
ansible.builtin.systemd:
name: "curl-{{ job.label }}.timer"
state: started
enabled: true
daemon_reload: true

View File

@@ -0,0 +1,19 @@
---
- name: "Install curl (Debian derivatives)"
when: ansible_os_family == "Debian"
ansible.builtin.apt:
name: curl
state: present
update_cache: true
- name: "Install curl (RHEL derivatives)"
when: ansible_os_family == "RedHat"
ansible.builtin.dnf:
name: curl
state: present
- name: "Configure and deploy systemd service"
loop: "{{ services }}"
loop_control:
loop_var: "job"
ansible.builtin.include_tasks: "deploy-service.yml"

View File

@@ -0,0 +1,21 @@
[Unit]
Description=Run an HTTP request via curl designated '{{ label }}'
After=network.target
[Service]
Type=oneshot
ExecStart={{ curl_cmd }} {{ curl_args }} "{{ url }}"
Restart=no
# Security hardening
ProtectSystem=strict
NoNewPrivileges=true
PrivateTmp=true
ProtectKernelModules=true
ProtectControlGroups=true
ProtectKernelTunables=true
ProtectClock=yes
RestrictSUIDSGID=true
[Install]
WantedBy=multi-user.targer

View File

@@ -0,0 +1,12 @@
[Unit]
Description=Trigger a curl command designated '{{ label }}'
Requires=curl-{{ label }}.service
[Timer]
Unit=curl-{{ label }}.service
OnCalendar={{ schedule }}
AccuracySec=1m
Persistent=true
[Install]
WantedBy=timers.target

View File

@@ -0,0 +1,2 @@
---
curl_scheduled_kuma_port: "3001"