Merge lp:~timkuhlman/charms/trusty/grafana/grafana-update into lp:~canonical-is-sa/charms/trusty/grafana/grafana

Proposed by Tim Kuhlman
Status: Merged
Merged at revision: 5
Proposed branch: lp:~timkuhlman/charms/trusty/grafana/grafana-update
Merge into: lp:~canonical-is-sa/charms/trusty/grafana/grafana
Diff against target: 356 lines (+246/-3)
13 files modified
config.yaml (+6/-1)
hooks/relations/http/README.md (+68/-0)
hooks/relations/http/interface.yaml (+4/-0)
hooks/relations/http/provides.py (+23/-0)
hooks/relations/http/requires.py (+58/-0)
hooks/website-relation-broken (+19/-0)
hooks/website-relation-changed (+19/-0)
hooks/website-relation-departed (+19/-0)
hooks/website-relation-joined (+19/-0)
layer.yaml (+1/-0)
lib/charms/layer/basic.py (+2/-1)
metadata.yaml (+2/-0)
reactive/grafana.py (+6/-1)
To merge this branch: bzr merge lp:~timkuhlman/charms/trusty/grafana/grafana-update
Reviewer Review Type Date Requested Status
Tim Kuhlman (community) Approve
Review via email: mp+293552@code.launchpad.net

Description of the change

Charm Build of the latest layer changes, including revno 36.

To post a comment you must log in.
Revision history for this message
Tim Kuhlman (timkuhlman) wrote :

I'll merge this as it was pointed out that since the layer was approved and this is just the result of 'charm build' on that layer there isn't much to review.

Revision history for this message
Tim Kuhlman (timkuhlman) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'config.yaml'
--- config.yaml 2016-04-27 16:21:44 +0000
+++ config.yaml 2016-05-02 16:56:01 +0000
@@ -55,8 +55,13 @@
55 "type": "string"55 "type": "string"
56 "description": |56 "description": |
57 Comma separated list of nagios servicegroups for the graphite check57 Comma separated list of nagios servicegroups for the graphite check
58 "port":
59 "type": "string"
60 "default": "3000"
61 "description": |
62 The port grafana will expose web services on.
58 "admin_password":63 "admin_password":
59 "default": !!null ""64 "default": ""
60 "type": "string"65 "type": "string"
61 "description": |66 "description": |
62 Grafana admin password. Default, pwgen(16) random password67 Grafana admin password. Default, pwgen(16) random password
6368
=== added directory 'hooks/relations/http'
=== added file 'hooks/relations/http/README.md'
--- hooks/relations/http/README.md 1970-01-01 00:00:00 +0000
+++ hooks/relations/http/README.md 2016-05-02 16:56:01 +0000
@@ -0,0 +1,68 @@
1# Overview
2
3This interface layer implements the basic form of the `http` interface protocol,
4which is used for things such as reverse-proxies, load-balanced servers, REST
5service discovery, et cetera.
6
7# Usage
8
9## Provides
10
11By providing the `http` interface, your charm is providing an HTTP server that
12can be load-balanced, reverse-proxied, used as a REST endpoint, etc.
13
14Your charm need only provide the port on which it is serving its content, as
15soon as the `{relation_name}.available` state is set:
16
17```python
18@when('website.available')
19def configure_website(website):
20 website.configure(port=hookenv.config('port'))
21```
22
23## Requires
24
25By requiring the `http` interface, your charm is consuming one or more HTTP
26servers, as a REST endpoint, to load-balance a set of servers, etc.
27
28Your charm should respond to the `{relation_name}.available` state, which
29indicates that there is at least one HTTP server connected.
30
31The `services()` method returns a list of available HTTP services and their
32associated hosts and ports.
33
34The return value is a list of dicts of the following form:
35
36```python
37[
38 {
39 'service_name': name_of_service,
40 'hosts': [
41 {
42 'hostname': address_of_host,
43 'port': port_for_host,
44 },
45 # ...
46 ],
47 },
48 # ...
49]
50```
51
52A trivial example of handling this interface would be:
53
54```python
55from charms.reactive.helpers import data_changed
56
57@when('reverseproxy.available')
58def update_reverse_proxy_config(reverseproxy):
59 services = reverseproxy.services()
60 if not data_changed('reverseproxy.services', services):
61 return
62 for service in services:
63 for host in service['hosts']:
64 hookenv.log('{} has a unit {}:{}'.format(
65 services['service_name'],
66 host['hostname'],
67 host['port']))
68```
069
=== added file 'hooks/relations/http/__init__.py'
=== added file 'hooks/relations/http/interface.yaml'
--- hooks/relations/http/interface.yaml 1970-01-01 00:00:00 +0000
+++ hooks/relations/http/interface.yaml 2016-05-02 16:56:01 +0000
@@ -0,0 +1,4 @@
1name: http
2summary: Basic HTTP interface
3version: 1
4repo: https://git.launchpad.net/~bcsaller/charms/+source/http
05
=== added file 'hooks/relations/http/provides.py'
--- hooks/relations/http/provides.py 1970-01-01 00:00:00 +0000
+++ hooks/relations/http/provides.py 2016-05-02 16:56:01 +0000
@@ -0,0 +1,23 @@
1from charmhelpers.core import hookenv
2from charms.reactive import hook
3from charms.reactive import RelationBase
4from charms.reactive import scopes
5
6
7class HttpProvides(RelationBase):
8 scope = scopes.GLOBAL
9
10 @hook('{provides:http}-relation-{joined,changed}')
11 def changed(self):
12 self.set_state('{relation_name}.available')
13
14 @hook('{provides:http}-relation-{broken,departed}')
15 def broken(self):
16 self.remove_state('{relation_name}.available')
17
18 def configure(self, port):
19 relation_info = {
20 'hostname': hookenv.unit_get('private-address'),
21 'port': port,
22 }
23 self.set_remote(**relation_info)
024
=== added file 'hooks/relations/http/requires.py'
--- hooks/relations/http/requires.py 1970-01-01 00:00:00 +0000
+++ hooks/relations/http/requires.py 2016-05-02 16:56:01 +0000
@@ -0,0 +1,58 @@
1from charms.reactive import hook
2from charms.reactive import RelationBase
3from charms.reactive import scopes
4
5
6class HttpRequires(RelationBase):
7 scope = scopes.UNIT
8
9 @hook('{requires:http}-relation-{joined,changed}')
10 def changed(self):
11 conv = self.conversation()
12 if conv.get_remote('port'):
13 # this unit's conversation has a port, so
14 # it is part of the set of available units
15 conv.set_state('{relation_name}.available')
16
17 @hook('{requires:http}-relation-{departed,broken}')
18 def broken(self):
19 conv = self.conversation()
20 conv.remove_state('{relation_name}.available')
21
22 def services(self):
23 """
24 Returns a list of available HTTP services and their associated hosts
25 and ports.
26
27 The return value is a list of dicts of the following form::
28
29 [
30 {
31 'service_name': name_of_service,
32 'hosts': [
33 {
34 'hostname': address_of_host,
35 'port': port_for_host,
36 },
37 # ...
38 ],
39 },
40 # ...
41 ]
42 """
43 services = {}
44 for conv in self.conversations():
45 service_name = conv.scope.split('/')[0]
46 service = services.setdefault(service_name, {
47 'service_name': service_name,
48 'hosts': [],
49 })
50 host = conv.get_remote('hostname') or \
51 conv.get_remote('private-address')
52 port = conv.get_remote('port')
53 if host and port:
54 service['hosts'].append({
55 'hostname': host,
56 'port': port,
57 })
58 return [s for s in services.values() if s['hosts']]
059
=== added file 'hooks/website-relation-broken'
--- hooks/website-relation-broken 1970-01-01 00:00:00 +0000
+++ hooks/website-relation-broken 2016-05-02 16:56:01 +0000
@@ -0,0 +1,19 @@
1#!/usr/bin/env python3
2
3# Load modules from $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 $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive,
14# and $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()
020
=== added file 'hooks/website-relation-changed'
--- hooks/website-relation-changed 1970-01-01 00:00:00 +0000
+++ hooks/website-relation-changed 2016-05-02 16:56:01 +0000
@@ -0,0 +1,19 @@
1#!/usr/bin/env python3
2
3# Load modules from $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 $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive,
14# and $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()
020
=== added file 'hooks/website-relation-departed'
--- hooks/website-relation-departed 1970-01-01 00:00:00 +0000
+++ hooks/website-relation-departed 2016-05-02 16:56:01 +0000
@@ -0,0 +1,19 @@
1#!/usr/bin/env python3
2
3# Load modules from $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 $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive,
14# and $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()
020
=== added file 'hooks/website-relation-joined'
--- hooks/website-relation-joined 1970-01-01 00:00:00 +0000
+++ hooks/website-relation-joined 2016-05-02 16:56:01 +0000
@@ -0,0 +1,19 @@
1#!/usr/bin/env python3
2
3# Load modules from $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 $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive,
14# and $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()
020
=== modified file 'layer.yaml'
--- layer.yaml 2016-04-27 15:11:18 +0000
+++ layer.yaml 2016-05-02 16:56:01 +0000
@@ -8,5 +8,6 @@
8- "layer:basic"8- "layer:basic"
9- "interface:nrpe-external-master"9- "interface:nrpe-external-master"
10- "interface:grafana-source"10- "interface:grafana-source"
11- "interface:http"
11"ignore": [".*.swp"]12"ignore": [".*.swp"]
12"is": "grafana"13"is": "grafana"
1314
=== modified file 'lib/charms/layer/basic.py'
--- lib/charms/layer/basic.py 2016-04-27 15:11:18 +0000
+++ lib/charms/layer/basic.py 2016-05-02 16:56:01 +0000
@@ -125,13 +125,14 @@
125 from charms.reactive import toggle_state125 from charms.reactive import toggle_state
126 config = hookenv.config()126 config = hookenv.config()
127 config_defaults = {}127 config_defaults = {}
128 config_defs = {}
128 config_yaml = os.path.join(hookenv.charm_dir(), 'config.yaml')129 config_yaml = os.path.join(hookenv.charm_dir(), 'config.yaml')
129 if os.path.exists(config_yaml):130 if os.path.exists(config_yaml):
130 with open(config_yaml) as fp:131 with open(config_yaml) as fp:
131 config_defs = yaml.load(fp).get('options', {})132 config_defs = yaml.load(fp).get('options', {})
132 config_defaults = {key: value.get('default')133 config_defaults = {key: value.get('default')
133 for key, value in config_defs.items()}134 for key, value in config_defs.items()}
134 for opt in config.keys():135 for opt in config_defs.keys():
135 if config.changed(opt):136 if config.changed(opt):
136 set_state('config.changed')137 set_state('config.changed')
137 set_state('config.changed.{}'.format(opt))138 set_state('config.changed.{}'.format(opt))
138139
=== modified file 'metadata.yaml'
--- metadata.yaml 2016-04-27 15:11:18 +0000
+++ metadata.yaml 2016-05-02 16:56:01 +0000
@@ -14,4 +14,6 @@
14 "nrpe-external-master":14 "nrpe-external-master":
15 "interface": "nrpe-external-master"15 "interface": "nrpe-external-master"
16 "scope": "container"16 "scope": "container"
17 "website":
18 "interface": "http"
17"subordinate": !!bool "false"19"subordinate": !!bool "false"
1820
=== modified file 'reactive/grafana.py'
--- reactive/grafana.py 2016-04-27 16:52:12 +0000
+++ reactive/grafana.py 2016-05-02 16:56:01 +0000
@@ -77,7 +77,7 @@
77 owner='root', group='grafana',77 owner='root', group='grafana',
78 perms=0o640,78 perms=0o640,
79 )79 )
80 check_ports(config.get('port', '3000'))80 check_ports(config.get('port'))
81 set_state('grafana.start')81 set_state('grafana.start')
82 hookenv.status_set('active', 'Ready')82 hookenv.status_set('active', 'Ready')
8383
@@ -148,6 +148,11 @@
148 pass148 pass
149149
150150
151@when('website.available')
152def configure_website(website):
153 website.configure(port=hookenv.config('port'))
154
155
151def validate_datasources():156def validate_datasources():
152 """TODO: make sure datasources option is merged with157 """TODO: make sure datasources option is merged with
153 relation data158 relation data

Subscribers

People subscribed via source and target branches

to all changes: