aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/tasks
diff options
context:
space:
mode:
authorColin Wilk <colin@wilk.cx>2026-08-11 00:54:41 +0200
committerColin Wilk <colin@wilk.cx>2026-08-11 00:54:41 +0200
commitc267536ecfbcf37e68226ade2ed29c3b1f356a98 (patch)
tree0fb9728b0095dd34b873fa6c137b75c60734940d /tasks
parentc33948c219032977779a7ef6d82c16e84f37b81a (diff)
downloadansible-role-prometheus-target-c267536ecfbcf37e68226ade2ed29c3b1f356a98.tar.gz
ansible-role-prometheus-target-c267536ecfbcf37e68226ade2ed29c3b1f356a98.zip
Add `state` option for removing exporters
Diffstat (limited to 'tasks')
-rw-r--r--tasks/process_exporter.yml7
-rw-r--r--tasks/strategy_lineinfile.yml14
-rw-r--r--tasks/strategy_yaml.yml37
3 files changed, 51 insertions, 7 deletions
diff --git a/tasks/process_exporter.yml b/tasks/process_exporter.yml
index b4f33ba..0a19480 100644
--- a/tasks/process_exporter.yml
+++ b/tasks/process_exporter.yml
@@ -12,6 +12,13 @@
{{ (item.host if item.host is defined else _defaults.host) | mandatory }}
_target_labels: >-
{{ (_defaults.labels | default({})) | combine(item.labels | default({})) }}
+ _target_state: >-
+ {{ item.state if item.state is defined else (_defaults.state | default('present')) }}
+
+- name: Validate exporter state
+ ansible.builtin.assert:
+ that: _target_state in ["present", "absent"]
+ fail_msg: "Exporter state must be 'present' or 'absent', got '{{ _target_state }}'"
- name: Execute strategy
ansible.builtin.include_tasks:
diff --git a/tasks/strategy_lineinfile.yml b/tasks/strategy_lineinfile.yml
index 7656602..2b2d02a 100644
--- a/tasks/strategy_lineinfile.yml
+++ b/tasks/strategy_lineinfile.yml
@@ -1,13 +1,23 @@
---
+- name: Check target file for removal
+ ansible.builtin.stat:
+ path: "{{ _target_path }}"
+ delegate_to: "{{ prometheus_target_host }}"
+ become: true
+ register: _target_file
+ when: _target_state == "absent"
+
- name: Deploy target via lineinfile
ansible.builtin.lineinfile:
path: "{{ _target_path }}"
line: "{{ prometheus_target_strategy_lineinfile_prefix ~ _target_host ~ prometheus_target_strategy_lineinfile_suffix }}"
- state: present
+ state: "{{ _target_state }}"
delegate_to: "{{ prometheus_target_host }}"
become: true
register: _lineinfile_result
+ when: _target_state == "present" or _target_file.stat.exists
- name: Track changes
ansible.builtin.set_fact:
- changed: "{{ changed | default(false) or _lineinfile_result.changed }}"
+ changed: >-
+ {{ changed | default(false) or (_lineinfile_result.changed | default(false)) }}
diff --git a/tasks/strategy_yaml.yml b/tasks/strategy_yaml.yml
index 24cd6c8..45b18c3 100644
--- a/tasks/strategy_yaml.yml
+++ b/tasks/strategy_yaml.yml
@@ -14,10 +14,22 @@
((exporter.path if exporter.path is defined else defaults.path) | mandatory) -%}
{%- set host = (exporter.host if exporter.host is defined else defaults.host) | mandatory -%}
{%- set labels = (defaults.labels | default({})) | combine(exporter.labels | default({})) -%}
- {%- set _ = ns.updates.append({'path': path, 'host': host, 'labels': labels}) -%}
+ {%- set target_state = exporter.state if exporter.state is defined else
+ (defaults.state | default('present')) -%}
+ {%- set _ = ns.updates.append(
+ {'path': path, 'host': host, 'labels': labels, 'state': target_state}) -%}
{%- endfor -%}
{{ ns.updates }}
+- name: Validate YAML exporter states
+ ansible.builtin.assert:
+ that: _yaml_update.state in ["present", "absent"]
+ fail_msg: "Exporter state must be 'present' or 'absent', got '{{ _yaml_update.state }}'"
+ loop: "{{ _prometheus_target_yaml_updates }}"
+ loop_control:
+ loop_var: _yaml_update
+ label: "{{ _yaml_update.path }}"
+
# Every play host prepares its values above. Applying all updates from one host
# prevents parallel Ansible forks from overwriting each other's YAML changes.
- name: Aggregate YAML exporter updates
@@ -56,14 +68,27 @@
_prometheus_target_yaml_files: >-
{%- set output = namespace(files=[]) -%}
{%- for file in _yaml_target_files.results -%}
+ {%- set file_updates = _prometheus_target_yaml_updates_all |
+ selectattr('path', 'equalto', file._yaml_path) | list -%}
+ {%- set present_updates = file_updates |
+ selectattr('state', 'equalto', 'present') | list -%}
{%- set state = namespace(groups=(file.content | b64decode | from_yaml)
if file.content is defined else []) -%}
{%- set state.groups = state.groups if state.groups is not none else [] -%}
- {%- for update in _prometheus_target_yaml_updates_all if update.path == file._yaml_path -%}
+ {%- for update in file_updates -%}
{%- set next = namespace(found=false, groups=[]) -%}
{%- for group in state.groups -%}
{%- set group_labels = group.labels | default({}) -%}
- {%- if group_labels == update.labels -%}
+ {%- if update.state == 'absent' -%}
+ {%- set filtered = group.targets | reject('equalto', update.host) | list -%}
+ {%- if filtered | length > 0 -%}
+ {%- set replacement = {'targets': filtered} -%}
+ {%- if group_labels | length > 0 -%}
+ {%- set _ = replacement.update({'labels': group_labels}) -%}
+ {%- endif -%}
+ {%- set _ = next.groups.append(replacement) -%}
+ {%- endif -%}
+ {%- elif group_labels == update.labels -%}
{%- if update.host not in group.targets -%}
{%- set _ = group.targets.append(update.host) -%}
{%- endif -%}
@@ -80,7 +105,7 @@
{%- endif -%}
{%- endif -%}
{%- endfor -%}
- {%- if not next.found -%}
+ {%- if update.state == 'present' and not next.found -%}
{%- set new_group = {'targets': [update.host]} -%}
{%- if update.labels | length > 0 -%}
{%- set _ = new_group.update({'labels': update.labels}) -%}
@@ -89,7 +114,9 @@
{%- endif -%}
{%- set state.groups = next.groups -%}
{%- endfor -%}
- {%- set _ = output.files.append({'path': file._yaml_path, 'groups': state.groups}) -%}
+ {%- if file.content is defined or present_updates | length > 0 -%}
+ {%- set _ = output.files.append({'path': file._yaml_path, 'groups': state.groups}) -%}
+ {%- endif -%}
{%- endfor -%}
{{ output.files }}
run_once: true