Merge ~jacekn/charm-prometheus-alertmanager:master into ~prometheus-charmers/charm-prometheus-alertmanager:master

Proposed by Jacek Nykis
Status: Merged
Approved by: David Lawson
Approved revision: d7f27d657f59206d87bc9d1f64a7eebe7ccc3526
Merged at revision: 20fc6ba3fc267b8ce1b6dc7d8ce112ccd6058c94
Proposed branch: ~jacekn/charm-prometheus-alertmanager:master
Merge into: ~prometheus-charmers/charm-prometheus-alertmanager:master
Diff against target: 234 lines (+101/-26)
8 files modified
hooks/alertmanager-cluster-relation-broken (+1/-0)
hooks/alertmanager-cluster-relation-changed (+1/-0)
hooks/alertmanager-cluster-relation-departed (+1/-0)
hooks/alertmanager-cluster-relation-joined (+1/-0)
hooks/defaulthook.py (+19/-0)
metadata.yaml (+3/-0)
reactive/alertmanager.py (+46/-11)
templates/daemon_arguments.j2 (+29/-15)
Reviewer Review Type Date Requested Status
Prometheus Charmers Pending
Review via email: mp+347141@code.launchpad.net

Commit message

Add support for clustering. Switch to long config option format now that snap supports it.

To post a comment you must log in.
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

This merge proposal is being monitored by mergebot. Change the status to Approved to merge.

Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

Change successfully merged at revision 20fc6ba3fc267b8ce1b6dc7d8ce112ccd6058c94

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/hooks/alertmanager-cluster-relation-broken b/hooks/alertmanager-cluster-relation-broken
0new file mode 1200000new file mode 120000
index 0000000..560258f
--- /dev/null
+++ b/hooks/alertmanager-cluster-relation-broken
@@ -0,0 +1 @@
1defaulthook.py
0\ No newline at end of file2\ No newline at end of file
diff --git a/hooks/alertmanager-cluster-relation-changed b/hooks/alertmanager-cluster-relation-changed
1new file mode 1200003new file mode 120000
index 0000000..560258f
--- /dev/null
+++ b/hooks/alertmanager-cluster-relation-changed
@@ -0,0 +1 @@
1defaulthook.py
0\ No newline at end of file2\ No newline at end of file
diff --git a/hooks/alertmanager-cluster-relation-departed b/hooks/alertmanager-cluster-relation-departed
1new file mode 1200003new file mode 120000
index 0000000..560258f
--- /dev/null
+++ b/hooks/alertmanager-cluster-relation-departed
@@ -0,0 +1 @@
1defaulthook.py
0\ No newline at end of file2\ No newline at end of file
diff --git a/hooks/alertmanager-cluster-relation-joined b/hooks/alertmanager-cluster-relation-joined
1new file mode 1200003new file mode 120000
index 0000000..560258f
--- /dev/null
+++ b/hooks/alertmanager-cluster-relation-joined
@@ -0,0 +1 @@
1defaulthook.py
0\ No newline at end of file2\ No newline at end of file
diff --git a/hooks/defaulthook.py b/hooks/defaulthook.py
1new file mode 1007553new file mode 100755
index 0000000..64c8489
--- /dev/null
+++ b/hooks/defaulthook.py
@@ -0,0 +1,19 @@
1#!/usr/bin/env python3
2
3# Load modules from $JUJU_CHARM_DIR/lib
4import sys
5sys.path.append('lib')
6
7from charms.layer import basic
8basic.bootstrap_charm_deps()
9basic.init_config_states()
10
11
12# This will load and run the appropriate @hook and other decorated
13# handlers from $JUJU_CHARM_DIR/reactive, $JUJU_CHARM_DIR/hooks/reactive,
14# and $JUJU_CHARM_DIR/hooks/relations.
15#
16# See https://jujucharms.com/docs/stable/authors-charm-building
17# for more information on this pattern.
18from charms.reactive import main
19main()
diff --git a/metadata.yaml b/metadata.yaml
index 6223e99..384d6ab 100644
--- a/metadata.yaml
+++ b/metadata.yaml
@@ -14,3 +14,6 @@ subordinate: false
14provides:14provides:
15 alertmanager-service:15 alertmanager-service:
16 interface: http16 interface: http
17peers:
18 alertmanager-cluster:
19 interface: alertmanger-cluster
diff --git a/reactive/alertmanager.py b/reactive/alertmanager.py
index 9ae82f5..6cc06c1 100644
--- a/reactive/alertmanager.py
+++ b/reactive/alertmanager.py
@@ -2,6 +2,7 @@ import yaml
22
3from charmhelpers.core import host, hookenv, unitdata3from charmhelpers.core import host, hookenv, unitdata
4from charmhelpers.core.templating import render4from charmhelpers.core.templating import render
5from charmhelpers import context
5from charms.reactive import (6from charms.reactive import (
6 when, when_not, when_any, set_state, remove_state7 when, when_not, when_any, set_state, remove_state
7)8)
@@ -21,6 +22,15 @@ def templates_changed(tmpl_list):
21 return any_file_changed(['templates/{}'.format(x) for x in tmpl_list])22 return any_file_changed(['templates/{}'.format(x) for x in tmpl_list])
2223
2324
25def get_peers():
26 peers = []
27 if not context.Relations().peer:
28 return False
29 for _, data in context.Relations().peer.items():
30 peers.append('{}:9094'.format(data.get('private-address')))
31 return sorted(peers)
32
33
24@when_not('alertmanager.installed')34@when_not('alertmanager.installed')
25def install_packages():35def install_packages():
26 hookenv.status_set('maintenance', 'Installing software')36 hookenv.status_set('maintenance', 'Installing software')
@@ -31,13 +41,32 @@ def install_packages():
31 set_state('alertmanager.do-check-reconfig')41 set_state('alertmanager.do-check-reconfig')
3242
3343
34def runtime_args(key=None, value=None):44def runtime_args(key=None, value=None, update=True):
35 kv = unitdata.kv()45 kv = unitdata.kv()
36 args = kv.get('runtime_args', {})46 args = kv.get('runtime_args', {})
37 if key:47 if key:
38 args.update({key: value})48 if update:
39 kv.set('runtime_args', args)49 args.update({key: value})
40 args_list = ['{} {}'.format(k, v) for k, v in args.items() if v]50 kv.set('runtime_args', args)
51 else:
52 if not args.get(key, []):
53 cur = set([])
54 else:
55 cur = set(args.get(key))
56 new = list(cur.union((value,)))
57 args.update({key: sorted(new)})
58 kv.set('runtime_args', args)
59
60 args_list = []
61 for k, v in args.items():
62 if not v:
63 continue
64 if isinstance(v, list):
65 for i in v:
66 args_list.append('{} {}'.format(k, i))
67 else:
68 args_list.append('{} {}'.format(k, v))
69
41 # sorted list is needed to avoid data_changed() false-positives70 # sorted list is needed to avoid data_changed() false-positives
42 return sorted(args_list)71 return sorted(args_list)
4372
@@ -72,7 +101,7 @@ def write_alertmanager_config_def():
72 config = hookenv.config()101 config = hookenv.config()
73 port = config.get('port', '9093')102 port = config.get('port', '9093')
74 check_ports(port)103 check_ports(port)
75 runtime_args('-web.listen-address',104 runtime_args('--web.listen-address',
76 ':{}'.format(port))105 ':{}'.format(port))
77 if config.get('external_url', False):106 if config.get('external_url', False):
78 vars = {107 vars = {
@@ -81,8 +110,16 @@ def write_alertmanager_config_def():
81 # alertmanager default:110 # alertmanager default:
82 'port': port,111 'port': port,
83 }112 }
84 runtime_args('-web.external-url',113 runtime_args('--web.external-url',
85 config['external_url'].format(**vars))114 config['external_url'].format(**vars))
115 if get_peers():
116 hookenv.log('Found cluster peers: {}'.format(get_peers()))
117 runtime_args('--mesh.listen-address', '0.0.0.0:9094')
118 for peer in get_peers():
119 runtime_args('--mesh.peer', peer, False)
120 else:
121 runtime_args('--mesh.listen-address', False)
122 runtime_args('--mesh.peer', False)
86 args = runtime_args()123 args = runtime_args()
87 hookenv.log('runtime_args: {}'.format(args))124 hookenv.log('runtime_args: {}'.format(args))
88 if args:125 if args:
@@ -101,11 +138,6 @@ def setup_alertmanager():
101 set_state('alertmanager.do-check-reconfig')138 set_state('alertmanager.do-check-reconfig')
102139
103140
104@when('alertmanager.started')
105def check_config():
106 set_state('alertmanager.do-check-reconfig')
107
108
109@when('alertmanager.installed')141@when('alertmanager.installed')
110@when_any('alertmanager.started', 'alertmanager.do-check-reconfig')142@when_any('alertmanager.started', 'alertmanager.do-check-reconfig')
111def check_reconfig_alertmanager():143def check_reconfig_alertmanager():
@@ -119,6 +151,9 @@ def check_reconfig_alertmanager():
119 set_state('alertmanager.do-reconfig-yml')151 set_state('alertmanager.do-reconfig-yml')
120 set_state('alertmanager.do-reconfig-def')152 set_state('alertmanager.do-reconfig-def')
121153
154 if data_changed('alertmanager.peers', get_peers()):
155 set_state('alertmanager.do-reconfig-def')
156
122 if templates_changed([ALERTMANAGER_YML_TMPL]):157 if templates_changed([ALERTMANAGER_YML_TMPL]):
123 set_state('alertmanager.do-reconfig-yml')158 set_state('alertmanager.do-reconfig-yml')
124159
diff --git a/templates/daemon_arguments.j2 b/templates/daemon_arguments.j2
index 624290b..fcc5da1 100644
--- a/templates/daemon_arguments.j2
+++ b/templates/daemon_arguments.j2
@@ -6,18 +6,32 @@ ARGS="
6{%- for arg in args -%}6{%- for arg in args -%}
7{{ arg }} {% endfor -%}7{{ arg }} {% endfor -%}
8"8"
9# Alertmanager supports the following options:9##############################################################################
10# -config.file string10# WARNINIG: Due to snap confinement the following options should not be set: #
11# Alertmanager configuration file name. (default "/etc/prometheus/alertmanager.yml")11##############################################################################
12# -log.format value12# --config.file
13# If set use a syslog logger or JSON logging. Example: logger:syslog?appname=bob&local=7 or logger:stdout?json=true. Defaults to stderr.13# --storage.path
14# -log.level value14
15# Only log messages with the given severity or above. Valid levels: [debug, info, warn, error, fatal]. (default info)15# Alertmanager supports the following options
16# -storage.path string16# --data.retention=120h How long to keep data for.
17# Base path for data storage. (default "/var/lib/prometheus/alertmanager/")17# --alerts.gc-interval=30m Interval between alert GC.
18# -version18# --log.level=info Only log messages with the given severity or above.
19# Print version information.19# --web.external-url=WEB.EXTERNAL-URL
20# -web.external-url string20# The URL under which Alertmanager is externally reachable (for example, if
21# The URL under which Alertmanager is externally reachable (for example, if Alertmanager is served via a reverse proxy). Used for generating relative and absolute links back to Alertmanager itself. If the URL has a path portion, it will be used to prefix all HTTP endpoints served by Alertmanager. If omitted, relevant URL components will be derived automatically.21# Alertmanager is served via a reverse proxy). Used for generating relative and
22# -web.listen-address string22# absolute links back to Alertmanager itself. If the URL has a path portion, it will
23# Address to listen on for the web interface and API. (default ":9093")23# be used to prefix all HTTP endpoints served by Alertmanager. If omitted, relevant
24# URL components will be derived automatically.
25# --web.route-prefix=WEB.ROUTE-PREFIX
26# Prefix for the internal routes of web endpoints. Defaults to path of
27# --web.external-url.
28# --web.listen-address=":9093"
29# Address to listen on for the web interface and API.
30# --mesh.listen-address="0.0.0.0:6783"
31# mesh listen address. Pass an empty string to disable.
32# --mesh.peer-id="52:54:00:54:c1:12"
33# mesh peer ID
34# --mesh.nickname="myhost" mesh peer nickname
35# --mesh.password="" password to join the peer network (empty password disables encryption)
36# --mesh.peer=MESH.PEER ... initial peers (may be repeated)
37# --version Show application version.

Subscribers

People subscribed via source and target branches