Merge lp:~ivoks/charm-helpers/vip-apache-context into lp:~openstack-charmers/charm-helpers/ssl-everywhere

Proposed by James Page
Status: Merged
Merged at revision: 139
Proposed branch: lp:~ivoks/charm-helpers/vip-apache-context
Merge into: lp:~openstack-charmers/charm-helpers/ssl-everywhere
Diff against target: 264 lines (+102/-15)
5 files modified
charmhelpers/contrib/openstack/context.py (+2/-0)
charmhelpers/contrib/templating/contexts.py (+35/-13)
tests/contrib/ansible/test_ansible.py (+5/-0)
tests/contrib/openstack/test_os_contexts.py (+2/-2)
tests/contrib/templating/test_contexts.py (+58/-0)
To merge this branch: bzr merge lp:~ivoks/charm-helpers/vip-apache-context
Reviewer Review Type Date Requested Status
charmers Pending
Review via email: mp+209012@code.launchpad.net

This proposal supersedes a proposal from 2014-03-02.

Description of the change

This merge allows us to use cluster VIP as ServerName in Apache. This is crucial with SSL, where ServerName needs to match CN in the certificate.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'charmhelpers/contrib/openstack/context.py'
2--- charmhelpers/contrib/openstack/context.py 2014-02-27 14:40:19 +0000
3+++ charmhelpers/contrib/openstack/context.py 2014-03-03 09:00:48 +0000
4@@ -432,6 +432,8 @@
5 'private_address': unit_get('private-address'),
6 'endpoints': []
7 }
8+ if is_clustered():
9+ ctxt['private_address'] = config('vip')
10 for api_port in self.external_ports:
11 ext_port = determine_apache_port(api_port)
12 int_port = determine_api_port(api_port)
13
14=== modified file 'charmhelpers/contrib/templating/contexts.py'
15--- charmhelpers/contrib/templating/contexts.py 2013-11-20 09:55:14 +0000
16+++ charmhelpers/contrib/templating/contexts.py 2014-03-03 09:00:48 +0000
17@@ -12,6 +12,37 @@
18 charm_dir = os.environ.get('CHARM_DIR', '')
19
20
21+def dict_keys_without_hyphens(a_dict):
22+ """Return the a new dict with underscores instead of hyphens in keys."""
23+ return dict(
24+ (key.replace('-', '_'), val) for key, val in a_dict.items())
25+
26+
27+def update_relations(context, namespace_separator=':'):
28+ """Update the context with the relation data."""
29+ # Add any relation data prefixed with the relation type.
30+ relation_type = charmhelpers.core.hookenv.relation_type()
31+ relations = []
32+ if relation_type is not None:
33+ relation_data = charmhelpers.core.hookenv.relation_get()
34+ relation_data = dict(
35+ ("{relation_type}{namespace_separator}{key}".format(
36+ relation_type=relation_type,
37+ key=key,
38+ namespace_separator=namespace_separator), val)
39+ for key, val in relation_data.items())
40+ relation_data = dict_keys_without_hyphens(relation_data)
41+ context.update(relation_data)
42+ relations = charmhelpers.core.hookenv.relations_of_type(relation_type)
43+ relations = [dict_keys_without_hyphens(rel) for rel in relations]
44+
45+ if 'relations' not in context:
46+ context['relations'] = {}
47+ if relation_type is not None:
48+ relation_type = relation_type.replace('-', '_')
49+ context['relations'][relation_type] = relations
50+
51+
52 def juju_state_to_yaml(yaml_path, namespace_separator=':',
53 allow_hyphens_in_keys=True):
54 """Update the juju config and state in a yaml file.
55@@ -37,17 +68,6 @@
56 config['charm_dir'] = charm_dir
57 config['local_unit'] = charmhelpers.core.hookenv.local_unit()
58
59- # Add any relation data prefixed with the relation type.
60- relation_type = charmhelpers.core.hookenv.relation_type()
61- if relation_type is not None:
62- relation_data = charmhelpers.core.hookenv.relation_get()
63- relation_data = dict(
64- ("{relation_type}{namespace_separator}{key}".format(
65- relation_type=relation_type.replace('-', '_'),
66- key=key,
67- namespace_separator=namespace_separator), val)
68- for key, val in relation_data.items())
69- config.update(relation_data)
70
71 # Don't use non-standard tags for unicode which will not
72 # work when salt uses yaml.load_safe.
73@@ -66,8 +86,10 @@
74 existing_vars = {}
75
76 if not allow_hyphens_in_keys:
77- config = dict(
78- (key.replace('-', '_'), val) for key, val in config.items())
79+ config = dict_keys_without_hyphens(config)
80 existing_vars.update(config)
81+
82+ update_relations(existing_vars, namespace_separator)
83+
84 with open(yaml_path, "w+") as fp:
85 fp.write(yaml.dump(existing_vars))
86
87=== modified file 'tests/contrib/ansible/test_ansible.py'
88--- tests/contrib/ansible/test_ansible.py 2013-11-20 10:05:22 +0000
89+++ tests/contrib/ansible/test_ansible.py 2014-03-03 09:00:48 +0000
90@@ -78,6 +78,10 @@
91 self.mock_relation_get = patcher.start()
92 self.mock_relation_get.return_value = {}
93 self.addCleanup(patcher.stop)
94+ patcher = mock.patch('charmhelpers.core.hookenv.relations_of_type')
95+ self.mock_relations_of_type = patcher.start()
96+ self.mock_relations_of_type.return_value = []
97+ self.addCleanup(patcher.stop)
98 patcher = mock.patch('charmhelpers.core.hookenv.relation_type')
99 self.mock_relation_type = patcher.start()
100 self.mock_relation_type.return_value = None
101@@ -131,6 +135,7 @@
102 "private_address": "10.10.10.10",
103 "charm_dir": "",
104 "local_unit": {},
105+ 'relations': {'wsgi_file': []},
106 "wsgi_file__relation_key1": "relation_value1",
107 "wsgi_file__relation_key2": "relation_value2",
108 }, result)
109
110=== modified file 'tests/contrib/openstack/test_os_contexts.py'
111--- tests/contrib/openstack/test_os_contexts.py 2014-02-27 14:40:19 +0000
112+++ tests/contrib/openstack/test_os_contexts.py 2014-03-03 09:00:48 +0000
113@@ -723,7 +723,7 @@
114 mock_neutron_ctxt):
115
116 mock_neutron_ctxt.return_value = {'network_manager': 'neutron',
117- 'neutron_url': 'https://foo:9292'}
118+ 'neutron_url': 'https://foo:9696'}
119 config = {'neutron-alchemy-flags': None}
120 self.config.side_effect = lambda key: config[key]
121 neutron = context.NeutronContext()
122@@ -745,7 +745,7 @@
123 self.assertEquals(
124 {'network_manager': 'neutron',
125 'ovs': 'ovs_context',
126- 'neutron_url': 'https://foo:9292'},
127+ 'neutron_url': 'https://foo:9696'},
128 neutron()
129 )
130
131
132=== modified file 'tests/contrib/templating/test_contexts.py'
133--- tests/contrib/templating/test_contexts.py 2013-11-20 09:55:14 +0000
134+++ tests/contrib/templating/test_contexts.py 2014-03-03 09:00:48 +0000
135@@ -32,6 +32,10 @@
136 patcher = mock.patch('charmhelpers.core.hookenv.local_unit')
137 self.mock_local_unit = patcher.start()
138 self.addCleanup(patcher.stop)
139+ patcher = mock.patch('charmhelpers.core.hookenv.relations_of_type')
140+ self.mock_relations_of_type = patcher.start()
141+ self.addCleanup(patcher.stop)
142+ self.mock_relations_of_type.return_value = []
143
144 # patches specific to this test class.
145 etc_dir = tempfile.mkdtemp()
146@@ -59,6 +63,7 @@
147 "charm_dir": "/tmp/charm_dir",
148 "group_code_owner": "webops_deploy",
149 "user_code_runner": "ubunet",
150+ "relations": {},
151 "local_unit": "click-index/3",
152 }, result)
153
154@@ -80,6 +85,7 @@
155 "group_code_owner": "webops_deploy",
156 "user_code_runner": "ubunet",
157 "local_unit": "click-index/3",
158+ "relations": {},
159 }, result)
160
161 def test_output_with_relation(self):
162@@ -106,8 +112,46 @@
163 "wsgi_file:relation_key1": "relation_value1",
164 "wsgi_file:relation_key2": "relation_value2",
165 "local_unit": "click-index/3",
166+ "relations": {"wsgi_file": []},
167 }, result)
168
169+ def test_output_with_multiple_relations(self):
170+ self.mock_config.return_value = {
171+ 'group_code_owner': 'webops_deploy',
172+ 'user_code_runner': 'ubunet',
173+ }
174+ self.mock_relation_type.return_value = 'cluster'
175+ self.mock_relation_get.return_value = {
176+ 'private-address': '10.0.3.105',
177+ }
178+ self.mock_local_unit.return_value = "click-index/3"
179+ self.mock_relations_of_type.return_value = [{
180+ u'private-address': u'10.0.3.105',
181+ '__unit__': u'elasticsearch/1',
182+ '__relid__': u'cluster:0',
183+ }, {
184+ u'private-address': u'10.0.3.107',
185+ '__unit__': u'elasticsearch/2',
186+ '__relid__': u'cluster:0',
187+ }]
188+
189+ charmhelpers.contrib.templating.contexts.juju_state_to_yaml(
190+ self.context_path)
191+
192+ with open(self.context_path, 'r') as context_file:
193+ result = yaml.load(context_file.read())
194+ self.assertIn('relations', result)
195+ self.assertIn('cluster', result['relations'])
196+ self.assertEqual([{
197+ u'private_address': u'10.0.3.105',
198+ '__unit__': u'elasticsearch/1',
199+ '__relid__': u'cluster:0',
200+ }, {
201+ u'private_address': u'10.0.3.107',
202+ '__unit__': u'elasticsearch/2',
203+ '__relid__': u'cluster:0',
204+ }], result['relations']['cluster'])
205+
206 def test_relation_with_separator(self):
207 self.mock_config.return_value = {
208 'group_code_owner': 'webops_deploy',
209@@ -132,6 +176,7 @@
210 "wsgi_file__relation_key1": "relation_value1",
211 "wsgi_file__relation_key2": "relation_value2",
212 "local_unit": "click-index/3",
213+ "relations": {"wsgi_file": []},
214 }, result)
215
216 def test_updates_existing_values(self):
217@@ -145,6 +190,9 @@
218 context_file.write(yaml.dump({
219 'solr:hostname': 'example.com',
220 'user_code_runner': 'oldvalue',
221+ 'relations': {
222+ 'website': [{u'private_address': u'10.0.3.107'}],
223+ }
224 }))
225
226 self.mock_config.return_value = charmhelpers.core.hookenv.Serializable({
227@@ -152,6 +200,10 @@
228 'user_code_runner': 'newvalue',
229 })
230 self.mock_local_unit.return_value = "click-index/3"
231+ self.mock_relation_type.return_value = 'cluster'
232+ self.mock_relations_of_type.return_value = [{
233+ u'private-address': u'10.0.3.105',
234+ }]
235
236 charmhelpers.contrib.templating.contexts.juju_state_to_yaml(
237 self.context_path)
238@@ -164,6 +216,10 @@
239 "user_code_runner": "newvalue",
240 "local_unit": "click-index/3",
241 "solr:hostname": "example.com",
242+ "relations": {
243+ 'website': [{u'private_address': u'10.0.3.107'}],
244+ 'cluster': [{u'private_address': u'10.0.3.105'}],
245+ }
246 }, result)
247
248 def test_keys_with_hyphens(self):
249@@ -184,6 +240,7 @@
250 "charm_dir": "/tmp/charm_dir",
251 "group_code_owner": "webops_deploy",
252 "user_code_runner": "ubunet",
253+ "relations": {},
254 "local_unit": "click-index/3",
255 "private-address": "10.1.1.10",
256 }, result)
257@@ -212,6 +269,7 @@
258 "group_code_owner": "webops_deploy",
259 "user_code_runner": "ubunet",
260 "local_unit": "click-index/3",
261+ "relations": {"wsgi_file": []},
262 "private_address": "10.1.1.10",
263 "wsgi_file__relation_key1": "relation_value1",
264 "wsgi_file__relation_key2": "relation_value2",

Subscribers

People subscribed via source and target branches