OLD | NEW |
1 import os | 1 import os |
2 import yaml | 2 import yaml |
3 | 3 |
4 from charmhelpers.core import hookenv | 4 from charmhelpers.core.services import RelationContext |
5 from charmhelpers.contrib.openstack.context import OSContextGenerator | |
6 | 5 |
7 | 6 |
8 class RelationContext(OSContextGenerator): | 7 class StoredContext(dict): |
9 def __call__(self): | 8 """ |
10 if not hookenv.relation_ids(self.interface): | 9 A data context that always returns the data that it was first created with. |
11 return {} | 10 """ |
| 11 def __init__(self, file_name, config_data): |
| 12 """ |
| 13 If the file exists, populate `self` with the data from the file. |
| 14 Otherwise, populate with the given data and persist it to the file. |
| 15 """ |
| 16 if os.path.exists(file_name): |
| 17 self.update(self.read_context(file_name)) |
| 18 else: |
| 19 self.store_context(file_name, config_data) |
| 20 self.update(config_data) |
12 | 21 |
13 ctx = {} | 22 def store_context(self, file_name, config_data): |
14 for rid in hookenv.relation_ids(self.interface): | 23 with open(file_name, 'w') as file_stream: |
15 for unit in hookenv.related_units(rid): | 24 yaml.dump(config_data, file_stream) |
16 reldata = hookenv.relation_get(rid=rid, unit=unit) | |
17 required = set(self.required_keys) | |
18 if set(reldata.keys()).issuperset(required): | |
19 ns = ctx.setdefault(self.interface, {}) | |
20 for k, v in reldata.items(): | |
21 ns[k] = v | |
22 return ctx | |
23 | 25 |
24 return {} | 26 def read_context(self, file_name): |
| 27 with open(file_name, 'r') as file_stream: |
| 28 data = yaml.load(file_stream) |
| 29 if not data: |
| 30 raise OSError("%s is empty" % file_name) |
| 31 return data |
25 | 32 |
26 | 33 |
27 class ConfigContext(OSContextGenerator): | 34 class NatsRelation(RelationContext): |
28 def __call__(self): | 35 interface = 'nats' |
29 return hookenv.config() | 36 required_keys = ['address', 'port', 'user', 'password'] |
30 | 37 |
31 | 38 |
32 # Stores `config_data` hash into yaml file with `file_name` as a name | 39 class MysqlRelation(RelationContext): |
33 # if `file_name` already exists, then it loads data from `file_name`. | 40 interface = 'db' |
34 class StoredContext(OSContextGenerator): | 41 required_keys = ['user', 'password', 'host', 'database'] |
35 def __init__(self, file_name, config_data): | 42 dsn_template = "mysql2://{user}:{password}@{host}:{port}/{database}" |
36 self.data = config_data | |
37 if os.path.exists(file_name): | |
38 with open(file_name, 'r') as file_stream: | |
39 self.data = yaml.load(file_stream) | |
40 if not self.data: | |
41 raise OSError("%s is empty" % file_name) | |
42 else: | |
43 with open(file_name, 'w') as file_stream: | |
44 yaml.dump(config_data, file_stream) | |
45 self.data = config_data | |
46 | 43 |
47 def __call__(self): | 44 def get_data(self): |
48 return self.data | 45 RelationContext.get_data(self) |
| 46 if self.is_ready(): |
| 47 for unit in self['db']: |
| 48 if 'port' not in unit: |
| 49 unit['port'] = '3306' |
| 50 unit['dsn'] = self.dsn_template.format(**unit) |
49 | 51 |
50 | 52 |
51 class StaticContext(OSContextGenerator): | 53 class RouterRelation(RelationContext): |
52 def __init__(self, data): | |
53 self.data = data | |
54 | |
55 def __call__(self): | |
56 return self.data | |
57 | |
58 | |
59 class NatsContext(RelationContext): | |
60 interface = 'nats' | |
61 required_keys = ['nats_port', 'nats_address', 'nats_user', 'nats_password'] | |
62 | |
63 | |
64 class RouterContext(RelationContext): | |
65 interface = 'router' | 54 interface = 'router' |
66 required_keys = ['domain'] | 55 required_keys = ['domain'] |
67 | 56 |
68 class LogRouterContext(RelationContext): | 57 |
| 58 class LogRouterRelation(RelationContext): |
69 interface = 'logrouter' | 59 interface = 'logrouter' |
70 required_keys = ['shared-secret', 'logrouter-address'] | 60 required_keys = ['shared_secret', 'address', 'incoming_port', 'outgoing_port
'] |
| 61 |
| 62 |
| 63 class LoggregatorRelation(RelationContext): |
| 64 interface = 'loggregator' |
| 65 required_keys = ['address', 'incoming_port', 'outgoing_port'] |
| 66 |
| 67 |
| 68 class EtcdRelation(RelationContext): |
| 69 interface = 'etcd' |
| 70 required_keys = ['hostname', 'port'] |
| 71 |
| 72 |
| 73 class CloudControllerRelation(RelationContext): |
| 74 interface = 'cc' |
| 75 required_keys = ['hostname', 'port', 'user', 'password'] |
OLD | NEW |