blob: 24cd6c8840c34cb2b13b49ce5a4a49cdf2b70bcd (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
---
- name: Prepare YAML exporter updates
ansible.builtin.set_fact:
_prometheus_target_yaml_updates: >-
{%- set ns = namespace(updates=[]) -%}
{%- set exporters = prometheus_target_exporter +
([] if prometheus_target_skip_default_exporters else prometheus_target_default_exporters) -%}
{%- for exporter in exporters -%}
{%- set defaults = prometheus_target_exporter_defaults[exporter.id] | default({})
if exporter.id is defined else {} -%}
{%- set path =
(exporter.path_prefix if exporter.path_prefix is defined else
(defaults.path_prefix | default(prometheus_target_exporter_target_prefix))) ~
((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}) -%}
{%- endfor -%}
{{ ns.updates }}
# 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
ansible.builtin.set_fact:
_prometheus_target_yaml_updates_all: >-
{%- set ns = namespace(updates=[]) -%}
{%- for target_host in ansible_play_batch -%}
{%- for update in hostvars[target_host]._prometheus_target_yaml_updates -%}
{%- set _ = ns.updates.append(update) -%}
{%- endfor -%}
{%- endfor -%}
{{ ns.updates }}
run_once: true
- name: Collect YAML target paths
ansible.builtin.set_fact:
_prometheus_target_yaml_paths: >-
{{ _prometheus_target_yaml_updates_all | map(attribute='path') | unique | list }}
run_once: true
- name: Read YAML target files
ansible.builtin.slurp:
src: "{{ _yaml_path }}"
delegate_to: "{{ prometheus_target_host }}"
loop: "{{ _prometheus_target_yaml_paths }}"
loop_control:
loop_var: _yaml_path
register: _yaml_target_files
failed_when: false
run_once: true
# Build each destination completely in memory and write it once. Besides
# avoiding lost updates, this keeps updates to different files independent.
- name: Build updated YAML target files
ansible.builtin.set_fact:
_prometheus_target_yaml_files: >-
{%- set output = namespace(files=[]) -%}
{%- for file in _yaml_target_files.results -%}
{%- 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 -%}
{%- set next = namespace(found=false, groups=[]) -%}
{%- for group in state.groups -%}
{%- set group_labels = group.labels | default({}) -%}
{%- if group_labels == update.labels -%}
{%- if update.host not in group.targets -%}
{%- set _ = group.targets.append(update.host) -%}
{%- endif -%}
{%- set next.found = true -%}
{%- set _ = next.groups.append(group) -%}
{%- else -%}
{%- 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 -%}
{%- endif -%}
{%- endfor -%}
{%- if not next.found -%}
{%- set new_group = {'targets': [update.host]} -%}
{%- if update.labels | length > 0 -%}
{%- set _ = new_group.update({'labels': update.labels}) -%}
{%- endif -%}
{%- set _ = next.groups.append(new_group) -%}
{%- endif -%}
{%- set state.groups = next.groups -%}
{%- endfor -%}
{%- set _ = output.files.append({'path': file._yaml_path, 'groups': state.groups}) -%}
{%- endfor -%}
{{ output.files }}
run_once: true
- name: Write updated YAML target files
ansible.builtin.copy:
content: "{{ _yaml_file.groups | to_nice_yaml(indent=2, width=1337) }}"
dest: "{{ _yaml_file.path }}"
mode: "0644"
delegate_to: "{{ prometheus_target_host }}"
become: true
loop: "{{ _prometheus_target_yaml_files }}"
loop_control:
loop_var: _yaml_file
label: "{{ _yaml_file.path }}"
register: _yaml_results
run_once: true
- name: Track aggregated YAML changes on each host
ansible.builtin.set_fact:
changed: >-
{{ hostvars[ansible_play_batch | first]._yaml_results.results |
selectattr('changed') | list | length > 0 }}
|