Merge lp:~gnuoy/charms/trusty/neutron-api/add-ssl-support into lp:~openstack-charmers-archive/charms/trusty/neutron-api/next

Proposed by Liam Young
Status: Merged
Merged at revision: 36
Proposed branch: lp:~gnuoy/charms/trusty/neutron-api/add-ssl-support
Merge into: lp:~openstack-charmers-archive/charms/trusty/neutron-api/next
Diff against target: 302 lines (+122/-8)
7 files modified
config.yaml (+15/-0)
hooks/neutron_api_context.py (+19/-0)
hooks/neutron_api_hooks.py (+22/-0)
hooks/neutron_api_utils.py (+15/-0)
unit_tests/test_neutron_api_context.py (+6/-1)
unit_tests/test_neutron_api_hooks.py (+23/-2)
unit_tests/test_neutron_api_utils.py (+22/-5)
To merge this branch: bzr merge lp:~gnuoy/charms/trusty/neutron-api/add-ssl-support
Reviewer Review Type Date Requested Status
James Page Approve
Liam Young (community) Needs Resubmitting
Review via email: mp+224963@code.launchpad.net
To post a comment you must log in.
Revision history for this message
James Page (james-page) :
review: Needs Fixing
39. By Liam Young

* Add support for Apache < 2.4 and unit tests to support that.
* Fix typo in config.yaml

Revision history for this message
Liam Young (gnuoy) :
review: Needs Resubmitting
Revision history for this message
James Page (james-page) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'config.yaml'
2--- config.yaml 2014-06-24 11:05:17 +0000
3+++ config.yaml 2014-06-30 09:11:52 +0000
4@@ -89,3 +89,18 @@
5 default: False
6 type: boolean
7 description: Enable verbose logging
8+ ssl_cert:
9+ type: string
10+ description: |
11+ SSL certificate to install and use for API ports. Setting this value
12+ and ssl_key will enable reverse proxying, point Neutron's entry in the
13+ Keystone catalog to use https, and override any certficiate and key
14+ issued by Keystone (if it is configured to do so).
15+ ssl_key:
16+ type: string
17+ description: SSL key to use with certificate specified as ssl_cert.
18+ ssl_ca:
19+ type: string
20+ description: |
21+ SSL CA to use with the certificate and key provided - this is only
22+ required if you are providing a privately signed ssl_cert and ssl_key.
23
24=== modified file 'hooks/neutron_api_context.py'
25--- hooks/neutron_api_context.py 2014-06-25 10:48:41 +0000
26+++ hooks/neutron_api_context.py 2014-06-30 09:11:52 +0000
27@@ -5,6 +5,22 @@
28 relation_get,
29 )
30 from charmhelpers.contrib.openstack import context
31+from charmhelpers.contrib.hahelpers.cluster import (
32+ determine_api_port,
33+)
34+
35+
36+class ApacheSSLContext(context.ApacheSSLContext):
37+
38+ interfaces = ['https']
39+ external_ports = []
40+ service_namespace = 'neutron'
41+
42+ def __call__(self):
43+ # late import to work around circular dependency
44+ from neutron_api_utils import determine_ports
45+ self.external_ports = determine_ports()
46+ return super(ApacheSSLContext, self).__call__()
47
48
49 class IdentityServiceContext(context.IdentityServiceContext):
50@@ -41,10 +57,13 @@
51 pass
52
53 def __call__(self):
54+ from neutron_api_utils import api_port
55 ctxt = super(NeutronCCContext, self).__call__()
56 ctxt['external_network'] = config('neutron-external-network')
57 ctxt['verbose'] = config('verbose')
58 ctxt['debug'] = config('debug')
59+ ctxt['neutron_bind_port'] = \
60+ determine_api_port(api_port('neutron-server'))
61 for rid in relation_ids('neutron-api'):
62 for unit in related_units(rid):
63 ctxt['nova_url'] = relation_get(attribute='nova_url',
64
65=== modified file 'hooks/neutron_api_hooks.py'
66--- hooks/neutron_api_hooks.py 2014-06-23 11:18:17 +0000
67+++ hooks/neutron_api_hooks.py 2014-06-30 09:11:52 +0000
68@@ -2,6 +2,7 @@
69
70 import sys
71
72+from subprocess import check_call
73 from charmhelpers.core.hookenv import (
74 Hooks,
75 UnregisteredHookError,
76@@ -56,6 +57,25 @@
77 CONFIGS = register_configs()
78
79
80+def configure_https():
81+ '''
82+ Enables SSL API Apache config if appropriate and kicks identity-service
83+ with any required api updates.
84+ '''
85+ # need to write all to ensure changes to the entire request pipeline
86+ # propagate (c-api, haprxy, apache)
87+ CONFIGS.write_all()
88+ if 'https' in CONFIGS.complete_contexts():
89+ cmd = ['a2ensite', 'openstack_https_frontend']
90+ check_call(cmd)
91+ else:
92+ cmd = ['a2dissite', 'openstack_https_frontend']
93+ check_call(cmd)
94+
95+ for rid in relation_ids('identity-service'):
96+ identity_joined(rid=rid)
97+
98+
99 @hooks.hook()
100 def install():
101 execd_preinstall()
102@@ -72,6 +92,7 @@
103 global CONFIGS
104 if openstack_upgrade_available('neutron-server'):
105 do_openstack_upgrade(CONFIGS)
106+ configure_https()
107 CONFIGS.write_all()
108 for r_id in relation_ids('neutron-api'):
109 neutron_api_relation_joined(rid=r_id)
110@@ -165,6 +186,7 @@
111 CONFIGS.write(NEUTRON_CONF)
112 for r_id in relation_ids('neutron-api'):
113 neutron_api_relation_joined(rid=r_id)
114+ configure_https()
115
116
117 @hooks.hook('neutron-api-relation-joined')
118
119=== modified file 'hooks/neutron_api_utils.py'
120--- hooks/neutron_api_utils.py 2014-06-23 11:18:17 +0000
121+++ hooks/neutron_api_utils.py 2014-06-30 09:11:52 +0000
122@@ -26,6 +26,8 @@
123
124 # removed from original: charm-helper-sh
125 BASE_PACKAGES = [
126+ 'apache2',
127+ 'haproxy',
128 'python-keystoneclient',
129 'python-mysqldb',
130 'python-psycopg2',
131@@ -65,6 +67,14 @@
132 'services': ['neutron-server'],
133 'contexts': [neutron_api_context.NeutronCCContext()],
134 }),
135+ (APACHE_CONF, {
136+ 'contexts': [neutron_api_context.ApacheSSLContext()],
137+ 'services': ['apache2'],
138+ }),
139+ (APACHE_24_CONF, {
140+ 'contexts': [neutron_api_context.ApacheSSLContext()],
141+ 'services': ['apache2'],
142+ }),
143 ])
144
145
146@@ -120,6 +130,11 @@
147 '''
148 resource_map = deepcopy(BASE_RESOURCE_MAP)
149
150+ if os.path.exists('/etc/apache2/conf-available'):
151+ resource_map.pop(APACHE_CONF)
152+ else:
153+ resource_map.pop(APACHE_24_CONF)
154+
155 # add neutron plugin requirements. nova-c-c only needs the neutron-server
156 # associated with configs, not the plugin agent.
157 plugin = config('neutron-plugin')
158
159=== modified file 'unit_tests/test_neutron_api_context.py'
160--- unit_tests/test_neutron_api_context.py 2014-06-20 10:02:09 +0000
161+++ unit_tests/test_neutron_api_context.py 2014-06-30 09:11:52 +0000
162@@ -7,6 +7,7 @@
163 'relation_ids',
164 'related_units',
165 'config',
166+ 'determine_api_port',
167 ]
168
169
170@@ -53,6 +54,8 @@
171 super(NeutronAPIContextsTest, self).setUp(context, TO_PATCH)
172 self.relation_get.side_effect = self.test_relation.get
173 self.config.side_effect = self.test_config.get
174+ self.api_port = 9696
175+ self.determine_api_port.return_value = self.api_port
176 self.test_config.set('neutron-plugin', 'ovs')
177 self.test_config.set('neutron-security-groups', True)
178 self.test_config.set('debug', True)
179@@ -70,7 +73,8 @@
180 ctxt_data = {
181 'debug': True,
182 'external_network': 'bob',
183- 'verbose': True
184+ 'neutron_bind_port': self.api_port,
185+ 'verbose': True,
186 }
187 with patch.object(napi_ctxt, '_ensure_packages'):
188 self.assertEquals(ctxt_data, napi_ctxt())
189@@ -85,6 +89,7 @@
190 self.test_relation.set({'nova_url': nova_url})
191 napi_ctxt = context.NeutronCCContext()
192 self.assertEquals(nova_url, napi_ctxt()['nova_url'])
193+ self.assertEquals(self.api_port, napi_ctxt()['neutron_bind_port'])
194
195 def test_neutroncc_context_manager(self):
196 napi_ctxt = context.NeutronCCContext()
197
198=== modified file 'unit_tests/test_neutron_api_hooks.py'
199--- unit_tests/test_neutron_api_hooks.py 2014-06-23 11:18:17 +0000
200+++ unit_tests/test_neutron_api_hooks.py 2014-06-30 09:11:52 +0000
201@@ -24,6 +24,7 @@
202 'canonical_url',
203 'config',
204 'CONFIGS',
205+ 'check_call',
206 'configure_installation_source',
207 'determine_endpoints',
208 'determine_packages',
209@@ -82,7 +83,8 @@
210 self.open_port.assert_has_calls(_port_calls)
211 self.assertTrue(self.execd_preinstall.called)
212
213- def test_config_changed(self):
214+ @patch.object(hooks, 'configure_https')
215+ def test_config_changed(self, conf_https):
216 self.openstack_upgrade_available.return_value = True
217 self.relation_ids.side_effect = self._fake_relids
218 _n_api_rel_joined = self.patch('neutron_api_relation_joined')
219@@ -192,7 +194,8 @@
220 self._call_hook('identity-service-relation-changed')
221 self.assertFalse(_api_rel_joined.called)
222
223- def test_identity_changed(self):
224+ @patch.object(hooks, 'configure_https')
225+ def test_identity_changed(self, conf_https):
226 self.CONFIGS.complete_contexts.return_value = ['identity-service']
227 _api_rel_joined = self.patch('neutron_api_relation_joined')
228 self.relation_ids.side_effect = self._fake_relids
229@@ -331,3 +334,21 @@
230 self._call_hook('ha-relation-changed')
231 self.assertFalse(_n_api_rel_joined.called)
232 self.assertFalse(_id_rel_joined.called)
233+
234+ def test_configure_https(self):
235+ self.CONFIGS.complete_contexts.return_value = ['https']
236+ self.relation_ids.side_effect = self._fake_relids
237+ _id_rel_joined = self.patch('identity_joined')
238+ hooks.configure_https()
239+ self.check_call.assert_called_with(['a2ensite',
240+ 'openstack_https_frontend'])
241+ self.assertTrue(_id_rel_joined.called)
242+
243+ def test_configure_https_nohttps(self):
244+ self.CONFIGS.complete_contexts.return_value = []
245+ self.relation_ids.side_effect = self._fake_relids
246+ _id_rel_joined = self.patch('identity_joined')
247+ hooks.configure_https()
248+ self.check_call.assert_called_with(['a2dissite',
249+ 'openstack_https_frontend'])
250+ self.assertTrue(_id_rel_joined.called)
251
252=== modified file 'unit_tests/test_neutron_api_utils.py'
253--- unit_tests/test_neutron_api_utils.py 2014-06-23 11:18:17 +0000
254+++ unit_tests/test_neutron_api_utils.py 2014-06-30 09:11:52 +0000
255@@ -85,10 +85,23 @@
256 port_list = nutils.determine_ports()
257 self.assertItemsEqual(port_list, [9696])
258
259- def test_resource_map(self):
260- _map = nutils.resource_map()
261- confs = [nutils.NEUTRON_CONF, nutils.NEUTRON_DEFAULT]
262- [self.assertIn(q_conf, _map.keys()) for q_conf in confs]
263+ @patch('os.path.exists')
264+ def test_resource_map(self, _path_exists):
265+ _path_exists.return_value = False
266+ _map = nutils.resource_map()
267+ confs = [nutils.NEUTRON_CONF, nutils.NEUTRON_DEFAULT,
268+ nutils.APACHE_CONF]
269+ [self.assertIn(q_conf, _map.keys()) for q_conf in confs]
270+ self.assertTrue(nutils.APACHE_24_CONF not in _map.keys())
271+
272+ @patch('os.path.exists')
273+ def test_resource_map_apache24(self, _path_exists):
274+ _path_exists.return_value = True
275+ _map = nutils.resource_map()
276+ confs = [nutils.NEUTRON_CONF, nutils.NEUTRON_DEFAULT,
277+ nutils.APACHE_24_CONF]
278+ [self.assertIn(q_conf, _map.keys()) for q_conf in confs]
279+ self.assertTrue(nutils.APACHE_CONF not in _map.keys())
280
281 def test_restart_map(self):
282 _restart_map = nutils.restart_map()
283@@ -103,6 +116,9 @@
284 (ML2CONF, {
285 'services': ['neutron-server'],
286 }),
287+ (nutils.APACHE_24_CONF, {
288+ 'services': ['apache2'],
289+ }),
290 ])
291 self.assertItemsEqual(_restart_map, expect)
292
293@@ -120,7 +136,8 @@
294 _regconfs = nutils.register_configs()
295 confs = ['/etc/neutron/neutron.conf',
296 '/etc/default/neutron-server',
297- '/etc/neutron/plugins/ml2/ml2_conf.ini']
298+ '/etc/neutron/plugins/ml2/ml2_conf.ini',
299+ '/etc/apache2/sites-available/openstack_https_frontend.conf']
300 self.assertItemsEqual(_regconfs.configs, confs)
301
302 @patch('os.path.isfile')

Subscribers

People subscribed via source and target branches