Merge ~jacekn/prometheus-charm:refresh into prometheus-charm:master

Proposed by Jacek Nykis
Status: Merged
Merged at revision: f1dd3fb1015af546b020f91d6cacd97808bad28c
Proposed branch: ~jacekn/prometheus-charm:refresh
Merge into: prometheus-charm:master
Diff against target: 177 lines (+87/-14)
3 files modified
config.yaml (+5/-0)
reactive/prometheus.py (+27/-14)
templates/refresh_rules.sh.j2 (+55/-0)
Reviewer Review Type Date Requested Status
Junien F Approve
Review via email: mp+318656@code.launchpad.net

Description of the change

Add script to refresh external rules

To post a comment you must log in.
Revision history for this message
Junien F (axino) wrote :

inline comments

review: Needs Fixing
Revision history for this message
Junien F (axino) wrote :

+1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/config.yaml b/config.yaml
index 4f4a2bc..0d1e4d9 100644
--- a/config.yaml
+++ b/config.yaml
@@ -109,6 +109,11 @@ options:
109 Plain text private SSH key used to for git authentication.109 Plain text private SSH key used to for git authentication.
110 Also see "rules-repo" config option110 Also see "rules-repo" config option
111 default: ""111 default: ""
112 rules-update-notify-email:
113 type: string
114 description: |
115 Email address that will receive cronned rule update failure emails
116 default: ""
112 external_url:117 external_url:
113 default: ""118 default: ""
114 type: string119 type: string
diff --git a/reactive/prometheus.py b/reactive/prometheus.py
index 0fc50ba..9e6f2b2 100644
--- a/reactive/prometheus.py
+++ b/reactive/prometheus.py
@@ -22,6 +22,8 @@ PROMETHEUS_YML_TMPL = 'prometheus.yml.j2'
22PROMETHEUS_DEF_TMPL = 'etc_default_prometheus.j2'22PROMETHEUS_DEF_TMPL = 'etc_default_prometheus.j2'
23PROMETHEUS_RULES_CRON = '/etc/cron.d/juju-prometheus-rules-refresh'23PROMETHEUS_RULES_CRON = '/etc/cron.d/juju-prometheus-rules-refresh'
24PROMETHEUS_SSH_KEYFILE = '/root/.ssh/prometheus_git_key'24PROMETHEUS_SSH_KEYFILE = '/root/.ssh/prometheus_git_key'
25REFRESH_RULES_SCRIPT = '/usr/local/bin/refresh_rules.sh'
26REFRESH_RULES_SCRIPT_TMPL = 'refresh_rules.sh.j2'
2527
2628
27def templates_changed(tmpl_list):29def templates_changed(tmpl_list):
@@ -75,28 +77,39 @@ def configure_rules():
75 set_state('prometheus.do-reconfig-yml')77 set_state('prometheus.do-reconfig-yml')
7678
77 if config.get('rules-repo', False):79 if config.get('rules-repo', False):
78 cron_ssh_command = ''80 ssh_command = ''
79 cli_ssh_command = ''
80 if config.get('rules-update-ssh-key', False):81 if config.get('rules-update-ssh-key', False):
81 host.mkdir(os.path.dirname(PROMETHEUS_SSH_KEYFILE), perms=0o700)82 host.mkdir(os.path.dirname(PROMETHEUS_SSH_KEYFILE), perms=0o700)
82 with open(PROMETHEUS_SSH_KEYFILE, 'w') as f:83 with open(PROMETHEUS_SSH_KEYFILE, 'w') as f:
83 f.write(config['rules-update-ssh-key'])84 f.write(config['rules-update-ssh-key'])
84 os.chmod(PROMETHEUS_SSH_KEYFILE, 0o600)85 os.chmod(PROMETHEUS_SSH_KEYFILE, 0o600)
85 cli_ssh_command = 'ssh -i {}'.format(PROMETHEUS_SSH_KEYFILE)86 ssh_command = 'ssh -i {}'.format(PROMETHEUS_SSH_KEYFILE)
86 cron_ssh_command = 'GIT_SSH_COMMAND="{}"'.format(cli_ssh_command)
8787
88 rules_path = get_paths()['external_rules_path']88 rules_path = get_paths()['external_rules_path']
89 if os.path.exists(rules_path):89 if os.path.exists(rules_path):
90 cmd = ['git', '-C', rules_path, 'pull']90 subprocess.check_call(['git', '-C', rules_path, 'pull'],
91 env={'GIT_SSH_COMMAND': ssh_command})
91 else:92 else:
92 # New repo, store key during initial clone93 # New repo, store key during initial clone
93 cli_ssh_command += ' -o StrictHostKeyChecking=no'94 subprocess.check_call(['git', 'clone', config['rules-repo'], rules_path],
94 cmd = ['git', 'clone', config['rules-repo'], rules_path]95 env={'GIT_SSH_COMMAND': ssh_command + ' -o StrictHostKeyChecking=no'})
95 subprocess.check_call(cmd, env={'GIT_SSH_COMMAND': cli_ssh_command})96
97 options = {
98 'prometheus_yml': get_paths()['prometheus_yml'],
99 'external_rules_path': get_paths()['external_rules_path'],
100 'promtool': get_paths()['promtool'],
101 'ssh_command': ssh_command,
102 'rules_update_notify_email': config.get('rules-update-notify-email', False),
103 }
104 render(source=REFRESH_RULES_SCRIPT_TMPL,
105 target=REFRESH_RULES_SCRIPT,
106 context=options,
107 perms=0o755,
108 )
96109
97 schedule = config.get('rules-update-schedule', '*/10 * * * *')110 schedule = config.get('rules-update-schedule', '*/10 * * * *')
98 with open(PROMETHEUS_RULES_CRON, 'w') as f:111 with open(PROMETHEUS_RULES_CRON, 'w') as f:
99 f.write('{} root {} git -C {} pull\n'.format(schedule, cron_ssh_command, rules_path))112 f.write('{} root {} &>/dev/null\n'.format(schedule, REFRESH_RULES_SCRIPT))
100 set_state('prometheus.do-reconfig-yml')113 set_state('prometheus.do-reconfig-yml')
101 remove_state('prometheus.do-reconfig-rules')114 remove_state('prometheus.do-reconfig-rules')
102115
@@ -168,6 +181,8 @@ def install_packages():
168 'revert install_method option to previous value')181 'revert install_method option to previous value')
169 return182 return
170183
184 if not os.path.exists('/usr/sbin/sendmail'):
185 fetch.apt_install('sendmail-bin') # Needed for cronjob email notifications
171 if source == 'snap':186 if source == 'snap':
172 snap.install(pkgname, channel=channel, force_dangerous=False)187 snap.install(pkgname, channel=channel, force_dangerous=False)
173 if config.get('prometheus_registration_listen', False):188 if config.get('prometheus_registration_listen', False):
@@ -401,7 +416,7 @@ def check_reconfig_prometheus():
401 install_opts = ('install_sources', 'install_keys', 'snap_channel',416 install_opts = ('install_sources', 'install_keys', 'snap_channel',
402 'prometheus_registration_listen')417 'prometheus_registration_listen')
403 def_change_opts = ('daemon-args', 'external_url')418 def_change_opts = ('daemon-args', 'external_url')
404 rules_change_opts = ('rules-repo', 'rules-update-schedule', 'rules-update-ssh-key')419 rules_change_opts = ('rules-repo', 'rules-update-schedule', 'rules-update-ssh-key', 'rules-update-notify-email')
405 yml_change_opts = set(config.keys()) - set(install_opts + def_change_opts + rules_change_opts)420 yml_change_opts = set(config.keys()) - set(install_opts + def_change_opts + rules_change_opts)
406 if any(config.changed(opt) for opt in install_opts):421 if any(config.changed(opt) for opt in install_opts):
407 set_state('prometheus.do-install')422 set_state('prometheus.do-install')
@@ -413,10 +428,6 @@ def check_reconfig_prometheus():
413 set_state('prometheus.do-reconfig-yml')428 set_state('prometheus.do-reconfig-yml')
414 if any((429 if any((
415 data_changed('prometheus.target_jobs', target_jobs),430 data_changed('prometheus.target_jobs', target_jobs),
416 templates_changed([PROMETHEUS_YML_TMPL]),
417 )):
418 set_state('prometheus.do-reconfig-yml')
419 if any((
420 data_changed('prometheus.scrape_jobs', scrape_jobs),431 data_changed('prometheus.scrape_jobs', scrape_jobs),
421 templates_changed([PROMETHEUS_YML_TMPL]),432 templates_changed([PROMETHEUS_YML_TMPL]),
422 )):433 )):
@@ -426,6 +437,8 @@ def check_reconfig_prometheus():
426 templates_changed([PROMETHEUS_DEF_TMPL]),437 templates_changed([PROMETHEUS_DEF_TMPL]),
427 )):438 )):
428 set_state('prometheus.do-reconfig-def')439 set_state('prometheus.do-reconfig-def')
440 if templates_changed([REFRESH_RULES_SCRIPT_TMPL]):
441 set_state('prometheus.do-reconfig-rules')
429 # Cron can update rules on disk, update-status hook can trigger config update442 # Cron can update rules on disk, update-status hook can trigger config update
430 if kv.get('prometheus.rule_files') != get_rule_files():443 if kv.get('prometheus.rule_files') != get_rule_files():
431 kv.set('prometheus.rule_files', get_rule_files())444 kv.set('prometheus.rule_files', get_rule_files())
diff --git a/templates/refresh_rules.sh.j2 b/templates/refresh_rules.sh.j2
432new file mode 100644445new file mode 100644
index 0000000..c880cc0
--- /dev/null
+++ b/templates/refresh_rules.sh.j2
@@ -0,0 +1,55 @@
1#!/bin/bash
2
3REPO_DIR={{ external_rules_path }}
4PROMTOOL={{ promtool }}
5PROM_YML={{ prometheus_yml }}
6GIT_SSH_COMMAND={{ cron_ssh_command }}
7if [ -n "${GIT_SSH_COMMAND}" ]; then
8 export GIT_SSH_COMMAND=${GIT_SSH_COMMAND}
9fi
10
11function notify_by_email {
12{% if rules_update_notify_email %}
13 /usr/sbin/sendmail -t << EOF
14To: {{ rules_update_notify_email }}
15From: {{ rules_update_notify_email }}
16Subject: Prometheus rule update failed on ${HOSTNAME}
17Automatic rules refresh on ${HOSTNAME} failed!
18
19Error: $1
20
21Please investigate
22EOF
23{% else %}
24echo "No email set, skipping notification"
25{% endif %}
26}
27
28cd $REPO_DIR
29echo "Running pre-update check"
30${PROMTOOL} check-config ${PROM_YML}
31if [ $? -eq 0 ]; then
32 git tag -f rules_live && git fetch && git merge --quiet --ff-only FETCH_HEAD
33 if [ $? -ne 0 ]; then
34 echo "Problem merging new rules"
35 notify_by_email "Problem merging new rules"
36 exit 1
37 fi
38else
39 echo "Pre-check failed, aborted refresh"
40 notify_by_email "Pre-check failed, aborted refresh"
41 exit 1
42fi
43
44echo "Running post-update check"
45${PROMTOOL} check-config ${PROM_YML}
46if [ $? -eq 0 ]; then
47 killall -HUP prometheus
48 git tag -f rules_live
49 echo "Update and reload complete"
50else
51 git reset --hard rules_live
52 echo "New rules did not pass verification, reverted"
53 notify_by_email "New rules did not pass verification, reverted"
54 exit 1
55fi

Subscribers

People subscribed via source and target branches