Skip to content

Commit 47634a5

Browse files
committed
Fixes #353 - Add health check command
Add a new foremanctl health command that verifies the state of all Foreman services after installation or during troubleshooting. Checks performed: - Core services running (foreman, httpd, redis, postgresql) - Dynflow workers running (orchestrator, worker, worker-hosts-queue) - Pulp services running (pulp-api, pulp-content) - Candlepin service running - Foreman API responding (GET /api/v2/ping) - Foreman tasks status (via Katello ping response) Reports a summary of all failures and exits non-zero if any check fails, making it suitable for scripting and CI use.
1 parent 5efa47a commit 47634a5

6 files changed

Lines changed: 122 additions & 0 deletions

File tree

.github/workflows/test.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ jobs:
120120
- name: Add optional features - azure-rm, google and remote-execution
121121
run: |
122122
./foremanctl deploy --add-feature azure-rm --add-feature google --add-feature remote-execution
123+
- name: Run health check
124+
run: |
125+
./foremanctl health
123126
- name: Run tests
124127
run: |
125128
./forge test --pytest-args="--certificate-source=${{ matrix.certificate_source }} --database-mode=${{ matrix.database }}"
@@ -241,6 +244,9 @@ jobs:
241244
- name: Run deployment
242245
run: |
243246
./foremanctl deploy
247+
- name: Run health check
248+
run: |
249+
./foremanctl health
244250
- name: Run tests
245251
run: |
246252
./forge test

src/filter_plugins/foremanctl.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ def available_foreman_proxy_plugins(_value):
9494
return compact_list(plugins)
9595

9696

97+
def has_feature(features, feature):
98+
"""Check if a feature is enabled - exact match or prefix (feature/)."""
99+
return feature in features or any(f.startswith(feature + '/') for f in features)
100+
97101
class FilterModule(object):
98102
'''foremanctl filters'''
99103

@@ -106,4 +110,5 @@ def filters(self):
106110
'available_foreman_proxy_plugins': available_foreman_proxy_plugins,
107111
'list_all_features': list_all_features,
108112
'invalid_features': invalid_features,
113+
'has_feature': has_feature,
109114
}

src/playbooks/health/health.yaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
- name: Run Foreman health checks
3+
hosts: quadlet
4+
become: true
5+
gather_facts: true
6+
vars_files:
7+
- "../../vars/defaults.yml"
8+
- "../../vars/flavors/{{ flavor }}.yml"
9+
- "../../vars/base.yaml"
10+
tasks:
11+
- name: Execute health checks
12+
ansible.builtin.include_role:
13+
name: checks
14+
tasks_from: execute_check
15+
loop:
16+
- check_services
17+
- check_foreman_api
18+
- name: Report status of health checks
19+
ansible.builtin.fail:
20+
msg: "{{ checks_results }}"
21+
when:
22+
- checks_results|default([])|length > 0
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
help: |
3+
Run health checks on Foreman services
4+
include:
5+
- _database_mode
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
- name: Check Foreman API responds
3+
ansible.builtin.uri:
4+
url: "{{ foreman_url }}/api/v2/ping"
5+
validate_certs: false
6+
status_code: 200
7+
timeout: 10
8+
register: check_foreman_api_ping
9+
10+
- name: Check Foreman tasks status
11+
ansible.builtin.assert:
12+
that:
13+
- check_foreman_api_ping.json.results.katello.services.foreman_tasks.status == 'ok'
14+
fail_msg: "Foreman tasks status: {{ check_foreman_api_ping.json.results.katello.services.foreman_tasks.status | default('unknown') }}"
15+
success_msg: "Foreman tasks status: ok"
16+
when:
17+
- enabled_features | has_feature('content')
18+
- check_foreman_api_ping.json.results.katello is defined
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
---
2+
- name: Gather service facts
3+
ansible.builtin.service_facts:
4+
5+
- name: Check core services are running
6+
ansible.builtin.assert:
7+
that:
8+
- "ansible_facts.services[item + '.service'] is defined"
9+
- "ansible_facts.services[item + '.service']['state'] == 'running'"
10+
fail_msg: "Service {{ item }} is not running"
11+
success_msg: "Service {{ item }} is running"
12+
loop:
13+
- foreman
14+
- httpd
15+
- redis
16+
17+
- name: Check PostgreSQL service is running
18+
ansible.builtin.assert:
19+
that:
20+
- "ansible_facts.services['postgresql.service'] is defined"
21+
- "ansible_facts.services['postgresql.service']['state'] == 'running'"
22+
fail_msg: "Service postgresql is not running"
23+
success_msg: "Service postgresql is running"
24+
when: database_mode | default('internal') == 'internal'
25+
26+
- name: Check dynflow services are running
27+
ansible.builtin.assert:
28+
that:
29+
- "ansible_facts.services[item + '.service'] is defined"
30+
- "ansible_facts.services[item + '.service']['state'] == 'running'"
31+
fail_msg: "Service {{ item }} is not running"
32+
success_msg: "Service {{ item }} is running"
33+
loop:
34+
- dynflow-sidekiq@orchestrator
35+
- dynflow-sidekiq@worker
36+
- dynflow-sidekiq@worker-hosts-queue
37+
38+
- name: Check Pulp services are running
39+
ansible.builtin.assert:
40+
that:
41+
- "ansible_facts.services[item + '.service'] is defined"
42+
- "ansible_facts.services[item + '.service']['state'] == 'running'"
43+
fail_msg: "Service {{ item }} is not running"
44+
success_msg: "Service {{ item }} is running"
45+
loop:
46+
- pulp-api
47+
- pulp-content
48+
when: enabled_features | has_feature('content')
49+
50+
- name: Check Candlepin service is running
51+
ansible.builtin.assert:
52+
that:
53+
- "ansible_facts.services['candlepin.service'] is defined"
54+
- "ansible_facts.services['candlepin.service']['state'] == 'running'"
55+
fail_msg: "Service candlepin is not running"
56+
success_msg: "Service candlepin is running"
57+
when: enabled_features | has_feature('content')
58+
59+
- name: Check Foreman Proxy service is running
60+
ansible.builtin.assert:
61+
that:
62+
- "ansible_facts.services['foreman-proxy.service'] is defined"
63+
- "ansible_facts.services['foreman-proxy.service']['state'] == 'running'"
64+
fail_msg: "Service foreman-proxy is not running"
65+
success_msg: "Service foreman-proxy is running"
66+
when: enabled_features | has_feature('foreman-proxy')

0 commit comments

Comments
 (0)