Left: | ||
Right: |
LEFT | RIGHT |
---|---|
1 #!/usr/bin/env python3 | 1 #!/usr/bin/env python3 |
2 | |
3 | 2 |
4 # Author: Charles Butler <charles.butler@canonical.com> | 3 # Author: Charles Butler <charles.butler@canonical.com> |
5 # Deploys elasticsearch and logstash-indexer | 4 # Deploys elasticsearch and logstash-indexer |
6 # Validates relationship presence, issues HTTPS request against | 5 # Validates relationship presence, issues HTTPS request against |
7 # elasticsearch cluster to validate scale, cluster name | 6 # elasticsearch cluster to validate scale, cluster name |
8 | |
9 | |
10 | |
11 | |
12 | |
13 import amulet | 7 import amulet |
14 import requests | 8 import requests |
15 import json | |
16 | 9 |
17 ########################################## | 10 ############################################################################### |
18 # Config Options | 11 # Config Options |
19 ########################################## | 12 ############################################################################### |
20 scale = 1 | 13 scale = 1 |
21 seconds = 900 | 14 seconds = 900 |
22 | 15 |
23 | 16 ############################################################################### |
24 | |
25 ################################################################################ ### | |
26 #Deployment Setup | 17 #Deployment Setup |
27 ################################################################################ ### | 18 ############################################################################### |
28 | |
29 | |
30 | 19 |
31 d = amulet.Deployment() | 20 d = amulet.Deployment() |
32 | 21 |
33 d.add('elasticsearch', units=scale) | 22 d.add('elasticsearch', units=scale) |
34 d.add('logstash-indexer') | 23 d.add('logstash-indexer') |
35 d.configure('elasticsearch', { 'cluster-name' : 'amulet-test' }) | 24 d.configure('elasticsearch', {'cluster-name': 'amulet-test'}) |
36 d.relate('elasticsearch:cluster', 'logstash-indexer:rest') | 25 d.relate('elasticsearch:cluster', 'logstash-indexer:rest') |
37 d.expose('elasticsearch') | 26 d.expose('elasticsearch') |
38 | 27 |
39 print(json.dumps(d.schema(), indent=2))·· | |
Marco Ceppi
2014/01/31 11:44:53
This is pretty much debugging, probably don't need
| |
40 | |
41 #perform deployment | 28 #perform deployment |
42 try: | 29 try: |
43 d.setup(timeout=seconds) | 30 d.setup(timeout=seconds) |
44 except amulet.helpers.TimeoutError: | 31 except amulet.helpers.TimeoutError: |
45 message = 'The environment did not setup in %d seconds.', seconds | 32 message = 'The environment did not setup in %d seconds.' % seconds |
46 amulet.raise_status(amulet.SKIP, msg=message) | 33 amulet.raise_status(amulet.SKIP, msg=message) |
47 except: | 34 except: |
48 raise | 35 raise |
49 | 36 |
50 | 37 ############################################################################### |
51 | |
52 | |
53 | |
54 ################################################################################ ### | |
55 # Service Health Checks | 38 # Service Health Checks |
56 ################################################################################ ### | 39 ############################################################################### |
57 | 40 # Elastic Search exposes a status RPC call, fetch the JSON and match against |
58 | |
59 # Elastic Search exposes a status RPC call, fetch the JSON and match against | |
60 # the following example template for nodes, cluster_name and status: | 41 # the following example template for nodes, cluster_name and status: |
61 #{ | 42 #{ |
62 # "cluster_name" : "elasticsearch", | 43 # "cluster_name" : "elasticsearch", |
63 # "status" : "green", | 44 # "status" : "green", |
64 # "timed_out" : false, | 45 # "timed_out" : false, |
65 # "number_of_nodes" : 1, | 46 # "number_of_nodes" : 1, |
66 # "number_of_data_nodes" : 1, | 47 # "number_of_data_nodes" : 1, |
67 # "active_primary_shards" : 0, | 48 # "active_primary_shards" : 0, |
68 # "active_shards" : 0, | 49 # "active_shards" : 0, |
69 # "relocating_shards" : 0, | 50 # "relocating_shards" : 0, |
70 # "initializing_shards" : 0, | 51 # "initializing_shards" : 0, |
71 # "unassigned_shards" : 0 | 52 # "unassigned_shards" : 0 |
72 #} | 53 #} |
73 | 54 |
74 | 55 |
75 def healthcheck(): | 56 def es_healthcheck(address=""): |
Marco Ceppi
2014/01/31 11:44:53
to avoid ambiguity with global variables, it might
| |
76 es_unit = d.sentry.unit['elasticsearch/0'] | 57 |
77 es_address = es_unit.info['public-address'] | 58 health = requests.get( |
78 ···· | 59 "http://{}:9200/_cluster/health".format(address), verify=False) |
79 health = requests.get("http://{}:9200/_cluster/health".format(es_address), v erify=False) | |
80 # Must return 200OK to pass | 60 # Must return 200OK to pass |
81 health.raise_for_status | 61 health.raise_for_status() |
Marco Ceppi
2014/01/31 11:44:53
This is a function, not a key. health.raise_for_st
| |
82 json_output = json.loads(health.content.decode()) | 62 json_output = health.json() |
Marco Ceppi
2014/01/31 11:44:53
json_output = health.json() would be better here
| |
83 | |
84 | |
85 | 63 |
86 # Validate cluster name from config was set | 64 # Validate cluster name from config was set |
87 if json_output['cluster_name'] != 'amulet-test': | 65 if json_output['cluster_name'] != 'amulet-test': |
88 amulet.raise_status(amulet.SKIP, msg="Configured cluster-name failed che ck") | 66 amulet.raise_status( |
Marco Ceppi
2014/01/31 11:44:53
This seems like a FAIL condition, not a SKIP
| |
89 | 67 amulet.FAIL, msg="Configured cluster-name failed check") |
68 | |
90 # validate unit scale | 69 # validate unit scale |
91 if json_output['number_of_nodes'] != scale : | 70 if json_output['number_of_nodes'] != scale: |
92 amulet.raise_status(amulet.SKIP, msg="Scale check failed, expected: {}, got: {}".format(scale, json_output['number_of_nodes'])) | 71 amulet.raise_status( |
Marco Ceppi
2014/01/31 11:44:53
Again, seems like a FAIL if it didn't configure pr
| |
72 amulet.FAIL, | |
73 msg="Scale check failed, expected: {}, got: {}".format( | |
74 scale, json_output['number_of_nodes'])) | |
93 | 75 |
94 | 76 |
95 | 77 ############################################################################### |
96 | 78 # Relationship Checks |
97 ################################################################################ ### | 79 ############################################################################### |
98 # Relationship Checks | |
99 ################################################################################ ### | |
100 | |
101 def relationships(): | 80 def relationships(): |
102 #Raises an error if the relationship is not set | 81 #Raises an error if the relationship is not set |
103 d.sentry.unit['elasticsearch/0'].relation('cluster', 'logstash-indexer:rest' ) | 82 d.sentry.unit['elasticsearch/0'].relation( |
83 'cluster', 'logstash-indexer:rest') | |
104 | 84 |
105 | 85 |
106 # Execute healthchecks before relationship check | 86 # Execute healthchecks before relationship check |
107 healthcheck() | 87 es_healthcheck(d.sentry.unit['elasticsearch/0'].info['public-address']) |
108 relationships() | 88 relationships() |
109 | |
110 | |
LEFT | RIGHT |