Merge lp:~xianghui/charms/trusty/nova-cloud-controller/lp1476455 into lp:~openstack-charmers-archive/charms/trusty/nova-cloud-controller/next
- Trusty Tahr (14.04)
- lp1476455
- Merge into next
Status: | Merged |
---|---|
Approved by: | Edward Hope-Morley |
Approved revision: | 187 |
Merged at revision: | 178 |
Proposed branch: | lp:~xianghui/charms/trusty/nova-cloud-controller/lp1476455 |
Merge into: | lp:~openstack-charmers-archive/charms/trusty/nova-cloud-controller/next |
Diff against target: |
442 lines (+278/-10) 11 files modified
config.yaml (+14/-0) hooks/nova_cc_context.py (+56/-0) hooks/nova_cc_hooks.py (+23/-4) hooks/nova_cc_utils.py (+2/-1) templates/icehouse/nova.conf (+2/-0) templates/juno/nova.conf (+2/-0) templates/kilo/nova.conf (+2/-0) templates/parts/novnc (+3/-0) templates/parts/spice (+4/-0) unit_tests/test_nova_cc_contexts.py (+148/-0) unit_tests/test_nova_cc_hooks.py (+22/-5) |
To merge this branch: | bzr merge lp:~xianghui/charms/trusty/nova-cloud-controller/lp1476455 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
OpenStack Charmers | Pending | ||
Edward Hope-Morley | Pending | ||
Review via email: mp+265759@code.launchpad.net |
This proposal supersedes a proposal from 2015-07-22.
Commit message
Description of the change
Support nova console session to be encrypted without nova API SSL.
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_unit_test #6247 nova-cloud-
UNIT OK: passed
Edward Hope-Morley (hopem) wrote : Posted in a previous version of this proposal | # |
See inline
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_lint_check #6618 nova-cloud-
LINT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_unit_test #6250 nova-cloud-
UNIT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_lint_check #6626 nova-cloud-
LINT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_unit_test #6253 nova-cloud-
UNIT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_amulet_test #5255 nova-cloud-
AMULET FAIL: amulet-test failed
AMULET Results (max last 2 lines):
make: *** [test] Error 1
ERROR:root:Make target returned non-zero.
Full amulet test output: http://
Build: http://
Edward Hope-Morley (hopem) wrote : Posted in a previous version of this proposal | # |
This all lgtm apart from one small comment. I'm gonna have a go at deploying it with your bundle before I +1 it tho. I also see that amulet failed but not sure if that is related.
Xiang Hui (xianghui) : Posted in a previous version of this proposal | # |
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_lint_check #6781 nova-cloud-
LINT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_unit_test #6408 nova-cloud-
UNIT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_amulet_test #5278 nova-cloud-
AMULET OK: passed
Build: http://
Edward Hope-Morley (hopem) : Posted in a previous version of this proposal | # |
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_lint_check #6886 nova-cloud-
LINT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_unit_test #6413 nova-cloud-
UNIT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_amulet_test #5328 nova-cloud-
AMULET OK: passed
Build: http://
Preview Diff
1 | === modified file 'config.yaml' | |||
2 | --- config.yaml 2015-07-10 14:14:23 +0000 | |||
3 | +++ config.yaml 2015-07-24 10:07:27 +0000 | |||
4 | @@ -381,3 +381,17 @@ | |||
5 | 381 | 381 | ||
6 | 382 | If memcached is being used to store the tokens, then it's recommended to | 382 | If memcached is being used to store the tokens, then it's recommended to |
7 | 383 | change this configuration to False. | 383 | change this configuration to False. |
8 | 384 | console-access-ssl-cert: | ||
9 | 385 | type: string | ||
10 | 386 | default: | ||
11 | 387 | description: | | ||
12 | 388 | Used for encrypting console connections. This differs from the SSL certificate | ||
13 | 389 | used for API endpoints and is used for console access session only. Setting | ||
14 | 390 | this value along with console-access-ssl-key will enable encrypted console | ||
15 | 391 | sessions. This has nothing to do with Nova API SSL and can be used | ||
16 | 392 | independently. This can be used in conjunction with console-access-protocol | ||
17 | 393 | set to 'novnc' or 'spice'. | ||
18 | 394 | console-access-ssl-key: | ||
19 | 395 | type: string | ||
20 | 396 | default: | ||
21 | 397 | description: SSL key to use with certificate specified as console-access-ssl-cert. | ||
22 | 384 | 398 | ||
23 | === modified file 'hooks/nova_cc_context.py' | |||
24 | --- hooks/nova_cc_context.py 2015-04-08 12:10:09 +0000 | |||
25 | +++ hooks/nova_cc_context.py 2015-07-24 10:07:27 +0000 | |||
26 | @@ -1,5 +1,6 @@ | |||
27 | 1 | import os | 1 | import os |
28 | 2 | 2 | ||
29 | 3 | from base64 import b64decode | ||
30 | 3 | from charmhelpers.core.hookenv import ( | 4 | from charmhelpers.core.hookenv import ( |
31 | 4 | config, | 5 | config, |
32 | 5 | relation_ids, | 6 | relation_ids, |
33 | @@ -9,6 +10,8 @@ | |||
34 | 9 | related_units, | 10 | related_units, |
35 | 10 | relations_for_id, | 11 | relations_for_id, |
36 | 11 | relation_get, | 12 | relation_get, |
37 | 13 | DEBUG, | ||
38 | 14 | unit_get, | ||
39 | 12 | ) | 15 | ) |
40 | 13 | from charmhelpers.fetch import ( | 16 | from charmhelpers.fetch import ( |
41 | 14 | apt_install, | 17 | apt_install, |
42 | @@ -23,6 +26,7 @@ | |||
43 | 23 | determine_apache_port, | 26 | determine_apache_port, |
44 | 24 | determine_api_port, | 27 | determine_api_port, |
45 | 25 | https, | 28 | https, |
46 | 29 | is_clustered, | ||
47 | 26 | ) | 30 | ) |
48 | 27 | from charmhelpers.contrib.network.ip import ( | 31 | from charmhelpers.contrib.network.ip import ( |
49 | 28 | format_ipv6_addr, | 32 | format_ipv6_addr, |
50 | @@ -30,6 +34,7 @@ | |||
51 | 30 | from charmhelpers.contrib.openstack.ip import ( | 34 | from charmhelpers.contrib.openstack.ip import ( |
52 | 31 | resolve_address, | 35 | resolve_address, |
53 | 32 | INTERNAL, | 36 | INTERNAL, |
54 | 37 | PUBLIC, | ||
55 | 33 | ) | 38 | ) |
56 | 34 | 39 | ||
57 | 35 | 40 | ||
58 | @@ -350,3 +355,54 @@ | |||
59 | 350 | ctxt['ssl_key'] = key | 355 | ctxt['ssl_key'] = key |
60 | 351 | 356 | ||
61 | 352 | return ctxt | 357 | return ctxt |
62 | 358 | |||
63 | 359 | |||
64 | 360 | class ConsoleSSLContext(context.OSContextGenerator): | ||
65 | 361 | interfaces = [] | ||
66 | 362 | |||
67 | 363 | def __call__(self): | ||
68 | 364 | ctxt = {} | ||
69 | 365 | from nova_cc_utils import console_attributes | ||
70 | 366 | |||
71 | 367 | if config('console-access-ssl-cert') \ | ||
72 | 368 | and config('console-access-ssl-key') \ | ||
73 | 369 | and config('console-access-protocol'): | ||
74 | 370 | ssl_dir = '/etc/nova/ssl/' | ||
75 | 371 | if not os.path.exists(ssl_dir): | ||
76 | 372 | log('Creating %s.' % ssl_dir, level=DEBUG) | ||
77 | 373 | os.mkdir(ssl_dir) | ||
78 | 374 | |||
79 | 375 | cert_path = os.path.join(ssl_dir, 'nova_cert.pem') | ||
80 | 376 | decode_ssl_cert = b64decode(config('console-access-ssl-cert')) | ||
81 | 377 | |||
82 | 378 | key_path = os.path.join(ssl_dir, 'nova_key.pem') | ||
83 | 379 | decode_ssl_key = b64decode(config('console-access-ssl-key')) | ||
84 | 380 | |||
85 | 381 | with open(cert_path, 'w') as fh: | ||
86 | 382 | fh.write(decode_ssl_cert) | ||
87 | 383 | with open(key_path, 'w') as fh: | ||
88 | 384 | fh.write(decode_ssl_key) | ||
89 | 385 | |||
90 | 386 | ctxt['ssl_only'] = True | ||
91 | 387 | ctxt['ssl_cert'] = cert_path | ||
92 | 388 | ctxt['ssl_key'] = key_path | ||
93 | 389 | |||
94 | 390 | if is_clustered(): | ||
95 | 391 | ip_addr = resolve_address(endpoint_type=PUBLIC) | ||
96 | 392 | else: | ||
97 | 393 | ip_addr = unit_get('private-address') | ||
98 | 394 | |||
99 | 395 | ip_addr = format_ipv6_addr(ip_addr) or ip_addr | ||
100 | 396 | |||
101 | 397 | _proto = config('console-access-protocol') | ||
102 | 398 | url = "https://%s:%s%s" % ( | ||
103 | 399 | ip_addr, | ||
104 | 400 | console_attributes('proxy-port', proto=_proto), | ||
105 | 401 | console_attributes('proxy-page', proto=_proto)) | ||
106 | 402 | |||
107 | 403 | if _proto == 'novnc': | ||
108 | 404 | ctxt['novncproxy_base_url'] = url | ||
109 | 405 | elif _proto == 'spice': | ||
110 | 406 | ctxt['html5proxy_base_url'] = url | ||
111 | 407 | |||
112 | 408 | return ctxt | ||
113 | 353 | 409 | ||
114 | === modified file 'hooks/nova_cc_hooks.py' | |||
115 | --- hooks/nova_cc_hooks.py 2015-06-12 13:03:50 +0000 | |||
116 | +++ hooks/nova_cc_hooks.py 2015-07-24 10:07:27 +0000 | |||
117 | @@ -106,13 +106,15 @@ | |||
118 | 106 | from charmhelpers.contrib.hahelpers.cluster import ( | 106 | from charmhelpers.contrib.hahelpers.cluster import ( |
119 | 107 | is_elected_leader, | 107 | is_elected_leader, |
120 | 108 | get_hacluster_config, | 108 | get_hacluster_config, |
121 | 109 | https, | ||
122 | 109 | ) | 110 | ) |
123 | 110 | 111 | ||
124 | 111 | from charmhelpers.payload.execd import execd_preinstall | 112 | from charmhelpers.payload.execd import execd_preinstall |
125 | 112 | 113 | ||
126 | 113 | from charmhelpers.contrib.openstack.ip import ( | 114 | from charmhelpers.contrib.openstack.ip import ( |
127 | 114 | canonical_url, | 115 | canonical_url, |
129 | 115 | PUBLIC, INTERNAL, ADMIN | 116 | PUBLIC, INTERNAL, ADMIN, |
130 | 117 | resolve_address, | ||
131 | 116 | ) | 118 | ) |
132 | 117 | 119 | ||
133 | 118 | from charmhelpers.contrib.network.ip import ( | 120 | from charmhelpers.contrib.network.ip import ( |
134 | @@ -120,7 +122,8 @@ | |||
135 | 120 | get_netmask_for_address, | 122 | get_netmask_for_address, |
136 | 121 | get_address_in_network, | 123 | get_address_in_network, |
137 | 122 | get_ipv6_addr, | 124 | get_ipv6_addr, |
139 | 123 | is_ipv6 | 125 | is_ipv6, |
140 | 126 | format_ipv6_addr, | ||
141 | 124 | ) | 127 | ) |
142 | 125 | 128 | ||
143 | 126 | from charmhelpers.contrib.openstack.context import ADDRESS_TYPES | 129 | from charmhelpers.contrib.openstack.context import ADDRESS_TYPES |
144 | @@ -511,10 +514,26 @@ | |||
145 | 511 | return {} | 514 | return {} |
146 | 512 | rel_settings['console_keymap'] = config('console-keymap') | 515 | rel_settings['console_keymap'] = config('console-keymap') |
147 | 513 | rel_settings['console_access_protocol'] = proto | 516 | rel_settings['console_access_protocol'] = proto |
148 | 517 | |||
149 | 518 | console_ssl = False | ||
150 | 519 | if config('console-access-ssl-cert') and config('console-access-ssl-key'): | ||
151 | 520 | console_ssl = True | ||
152 | 521 | |||
153 | 514 | if config('console-proxy-ip') == 'local': | 522 | if config('console-proxy-ip') == 'local': |
155 | 515 | proxy_base_addr = canonical_url(CONFIGS, PUBLIC) | 523 | if console_ssl: |
156 | 524 | address = resolve_address(endpoint_type=PUBLIC) | ||
157 | 525 | address = format_ipv6_addr(address) or address | ||
158 | 526 | proxy_base_addr = 'https://%s' % address | ||
159 | 527 | else: | ||
160 | 528 | # canonical_url will only return 'https:' if API SSL are enabled. | ||
161 | 529 | proxy_base_addr = canonical_url(CONFIGS, PUBLIC) | ||
162 | 516 | else: | 530 | else: |
164 | 517 | proxy_base_addr = "http://" + config('console-proxy-ip') | 531 | if console_ssl or https(): |
165 | 532 | schema = "https" | ||
166 | 533 | else: | ||
167 | 534 | schema = "http" | ||
168 | 535 | proxy_base_addr = "%s://%s" % (schema, config('console-proxy-ip')) | ||
169 | 536 | |||
170 | 518 | if proto == 'vnc': | 537 | if proto == 'vnc': |
171 | 519 | protocols = ['novnc', 'xvpvnc'] | 538 | protocols = ['novnc', 'xvpvnc'] |
172 | 520 | else: | 539 | else: |
173 | 521 | 540 | ||
174 | === modified file 'hooks/nova_cc_utils.py' | |||
175 | --- hooks/nova_cc_utils.py 2015-07-16 20:51:15 +0000 | |||
176 | +++ hooks/nova_cc_utils.py 2015-07-24 10:07:27 +0000 | |||
177 | @@ -194,7 +194,8 @@ | |||
178 | 194 | nova_cc_context.NovaIPv6Context(), | 194 | nova_cc_context.NovaIPv6Context(), |
179 | 195 | nova_cc_context.NeutronCCContext(), | 195 | nova_cc_context.NeutronCCContext(), |
180 | 196 | nova_cc_context.NovaConfigContext(), | 196 | nova_cc_context.NovaConfigContext(), |
182 | 197 | nova_cc_context.InstanceConsoleContext()], | 197 | nova_cc_context.InstanceConsoleContext(), |
183 | 198 | nova_cc_context.ConsoleSSLContext()], | ||
184 | 198 | }), | 199 | }), |
185 | 199 | (NOVA_API_PASTE, { | 200 | (NOVA_API_PASTE, { |
186 | 200 | 'services': [s for s in BASE_SERVICES if 'api' in s], | 201 | 'services': [s for s in BASE_SERVICES if 'api' in s], |
187 | 201 | 202 | ||
188 | === modified file 'templates/icehouse/nova.conf' | |||
189 | --- templates/icehouse/nova.conf 2015-04-10 02:39:10 +0000 | |||
190 | +++ templates/icehouse/nova.conf 2015-07-24 10:07:27 +0000 | |||
191 | @@ -165,3 +165,5 @@ | |||
192 | 165 | 165 | ||
193 | 166 | [conductor] | 166 | [conductor] |
194 | 167 | workers = {{ workers }} | 167 | workers = {{ workers }} |
195 | 168 | |||
196 | 169 | {% include "parts/spice" %} | ||
197 | 168 | 170 | ||
198 | === modified file 'templates/juno/nova.conf' | |||
199 | --- templates/juno/nova.conf 2015-04-13 08:49:59 +0000 | |||
200 | +++ templates/juno/nova.conf 2015-07-24 10:07:27 +0000 | |||
201 | @@ -160,3 +160,5 @@ | |||
202 | 160 | 160 | ||
203 | 161 | [conductor] | 161 | [conductor] |
204 | 162 | workers = {{ workers }} | 162 | workers = {{ workers }} |
205 | 163 | |||
206 | 164 | {% include "parts/spice" %} | ||
207 | 163 | 165 | ||
208 | === modified file 'templates/kilo/nova.conf' | |||
209 | --- templates/kilo/nova.conf 2015-04-13 08:49:59 +0000 | |||
210 | +++ templates/kilo/nova.conf 2015-07-24 10:07:27 +0000 | |||
211 | @@ -155,3 +155,5 @@ | |||
212 | 155 | 155 | ||
213 | 156 | [oslo_concurrency] | 156 | [oslo_concurrency] |
214 | 157 | lock_path=/var/lock/nova | 157 | lock_path=/var/lock/nova |
215 | 158 | |||
216 | 159 | {% include "parts/spice" %} | ||
217 | 158 | 160 | ||
218 | === modified file 'templates/parts/novnc' | |||
219 | --- templates/parts/novnc 2015-04-08 12:10:09 +0000 | |||
220 | +++ templates/parts/novnc 2015-07-24 10:07:27 +0000 | |||
221 | @@ -7,3 +7,6 @@ | |||
222 | 7 | {% if ssl_key -%} | 7 | {% if ssl_key -%} |
223 | 8 | key={{ ssl_key }} | 8 | key={{ ssl_key }} |
224 | 9 | {% endif %} | 9 | {% endif %} |
225 | 10 | {% if novncproxy_base_url -%} | ||
226 | 11 | novncproxy_base_url={{ novncproxy_base_url }} | ||
227 | 12 | {% endif %} | ||
228 | 10 | 13 | ||
229 | === added file 'templates/parts/spice' | |||
230 | --- templates/parts/spice 1970-01-01 00:00:00 +0000 | |||
231 | +++ templates/parts/spice 2015-07-24 10:07:27 +0000 | |||
232 | @@ -0,0 +1,4 @@ | |||
233 | 1 | [spice] | ||
234 | 2 | {% if html5proxy_base_url -%} | ||
235 | 3 | html5proxy_base_url = {{ html5proxy_base_url }} | ||
236 | 4 | {% endif -%} | ||
237 | 0 | 5 | ||
238 | === modified file 'unit_tests/test_nova_cc_contexts.py' | |||
239 | --- unit_tests/test_nova_cc_contexts.py 2015-06-11 13:33:42 +0000 | |||
240 | +++ unit_tests/test_nova_cc_contexts.py 2015-07-24 10:07:27 +0000 | |||
241 | @@ -148,3 +148,151 @@ | |||
242 | 148 | self.assertTrue(context.use_local_neutron_api()) | 148 | self.assertTrue(context.use_local_neutron_api()) |
243 | 149 | self.related_units.return_value = ['unit/0'] | 149 | self.related_units.return_value = ['unit/0'] |
244 | 150 | self.assertFalse(context.use_local_neutron_api()) | 150 | self.assertFalse(context.use_local_neutron_api()) |
245 | 151 | |||
246 | 152 | @mock.patch.object(context, 'config') | ||
247 | 153 | def test_console_access_ssl_disabled(self, mock_config): | ||
248 | 154 | config = {'console-access-ssl_cert': 'LS0tLS1CRUdJTiBDRV', | ||
249 | 155 | 'console-access-ssl_key': 'LS0tLS1CRUdJTiBQUk'} | ||
250 | 156 | mock_config.side_effect = lambda key: config.get(key) | ||
251 | 157 | |||
252 | 158 | ctxt = context.ConsoleSSLContext()() | ||
253 | 159 | self.assertEqual(ctxt, None) | ||
254 | 160 | |||
255 | 161 | config = {'console-access-ssl_cert': None, | ||
256 | 162 | 'console-access-ssl_key': None} | ||
257 | 163 | mock_config.side_effect = lambda key: config.get(key) | ||
258 | 164 | |||
259 | 165 | ctxt = context.ConsoleSSLContext()() | ||
260 | 166 | self.assertEqual(ctxt, None) | ||
261 | 167 | |||
262 | 168 | config = {'console-access-protocol': 'novnc', | ||
263 | 169 | 'console-access-ssl_cert': None, | ||
264 | 170 | 'console-access-ssl_key': None} | ||
265 | 171 | mock_config.side_effect = lambda key: config.get(key) | ||
266 | 172 | |||
267 | 173 | ctxt = context.ConsoleSSLContext()() | ||
268 | 174 | self.assertEqual(ctxt, None) | ||
269 | 175 | |||
270 | 176 | @mock.patch('__builtin__.open') | ||
271 | 177 | @mock.patch('os.path.exists') | ||
272 | 178 | @mock.patch.object(context, 'config') | ||
273 | 179 | @mock.patch.object(context, 'unit_get') | ||
274 | 180 | @mock.patch.object(context, 'is_clustered') | ||
275 | 181 | @mock.patch.object(context, 'resolve_address') | ||
276 | 182 | @mock.patch.object(context, 'b64decode') | ||
277 | 183 | def test_noVNC_ssl_enabled(self, mock_b64decode, | ||
278 | 184 | mock_resolve_address, | ||
279 | 185 | mock_is_clustered, mock_unit_get, | ||
280 | 186 | mock_config, mock_exists, mock_open): | ||
281 | 187 | config = {'console-access-ssl-cert': 'LS0tLS1CRUdJTiBDRV', | ||
282 | 188 | 'console-access-ssl-key': 'LS0tLS1CRUdJTiBQUk', | ||
283 | 189 | 'console-access-protocol': 'novnc'} | ||
284 | 190 | mock_config.side_effect = lambda key: config.get(key) | ||
285 | 191 | mock_exists.return_value = True | ||
286 | 192 | mock_unit_get.return_value = '127.0.0.1' | ||
287 | 193 | mock_is_clustered.return_value = True | ||
288 | 194 | mock_resolve_address.return_value = '10.5.100.1' | ||
289 | 195 | mock_b64decode.return_value = 'decode_success' | ||
290 | 196 | |||
291 | 197 | mock_open.return_value.__enter__ = lambda s: s | ||
292 | 198 | mock_open.return_value.__exit__ = mock.Mock() | ||
293 | 199 | |||
294 | 200 | ctxt = context.ConsoleSSLContext()() | ||
295 | 201 | self.assertTrue(ctxt['ssl_only']) | ||
296 | 202 | self.assertEqual(ctxt['ssl_cert'], '/etc/nova/ssl/nova_cert.pem') | ||
297 | 203 | self.assertEqual(ctxt['ssl_key'], '/etc/nova/ssl/nova_key.pem') | ||
298 | 204 | self.assertEqual(ctxt['novncproxy_base_url'], | ||
299 | 205 | 'https://10.5.100.1:6080/vnc_auto.html') | ||
300 | 206 | |||
301 | 207 | @mock.patch('__builtin__.open') | ||
302 | 208 | @mock.patch('os.path.exists') | ||
303 | 209 | @mock.patch.object(context, 'config') | ||
304 | 210 | @mock.patch.object(context, 'unit_get') | ||
305 | 211 | @mock.patch.object(context, 'is_clustered') | ||
306 | 212 | @mock.patch.object(context, 'resolve_address') | ||
307 | 213 | @mock.patch.object(context, 'b64decode') | ||
308 | 214 | def test_noVNC_ssl_enabled_no_cluster(self, mock_b64decode, | ||
309 | 215 | mock_resolve_address, | ||
310 | 216 | mock_is_clustered, mock_unit_get, | ||
311 | 217 | mock_config, mock_exists, mock_open): | ||
312 | 218 | config = {'console-access-ssl-cert': 'LS0tLS1CRUdJTiBDRV', | ||
313 | 219 | 'console-access-ssl-key': 'LS0tLS1CRUdJTiBQUk', | ||
314 | 220 | 'console-access-protocol': 'novnc'} | ||
315 | 221 | mock_config.side_effect = lambda key: config.get(key) | ||
316 | 222 | mock_exists.return_value = True | ||
317 | 223 | mock_unit_get.return_value = '10.5.0.1' | ||
318 | 224 | mock_is_clustered.return_value = False | ||
319 | 225 | mock_b64decode.return_value = 'decode_success' | ||
320 | 226 | |||
321 | 227 | mock_open.return_value.__enter__ = lambda s: s | ||
322 | 228 | mock_open.return_value.__exit__ = mock.Mock() | ||
323 | 229 | |||
324 | 230 | ctxt = context.ConsoleSSLContext()() | ||
325 | 231 | self.assertTrue(ctxt['ssl_only']) | ||
326 | 232 | self.assertEqual(ctxt['ssl_cert'], '/etc/nova/ssl/nova_cert.pem') | ||
327 | 233 | self.assertEqual(ctxt['ssl_key'], '/etc/nova/ssl/nova_key.pem') | ||
328 | 234 | self.assertEqual(ctxt['novncproxy_base_url'], | ||
329 | 235 | 'https://10.5.0.1:6080/vnc_auto.html') | ||
330 | 236 | |||
331 | 237 | @mock.patch('__builtin__.open') | ||
332 | 238 | @mock.patch('os.path.exists') | ||
333 | 239 | @mock.patch.object(context, 'config') | ||
334 | 240 | @mock.patch.object(context, 'unit_get') | ||
335 | 241 | @mock.patch.object(context, 'is_clustered') | ||
336 | 242 | @mock.patch.object(context, 'resolve_address') | ||
337 | 243 | @mock.patch.object(context, 'b64decode') | ||
338 | 244 | def test_spice_html5_ssl_enabled(self, mock_b64decode, | ||
339 | 245 | mock_resolve_address, | ||
340 | 246 | mock_is_clustered, mock_unit_get, | ||
341 | 247 | mock_config, mock_exists, mock_open): | ||
342 | 248 | config = {'console-access-ssl-cert': 'LS0tLS1CRUdJTiBDRV', | ||
343 | 249 | 'console-access-ssl-key': 'LS0tLS1CRUdJTiBQUk', | ||
344 | 250 | 'console-access-protocol': 'spice'} | ||
345 | 251 | mock_config.side_effect = lambda key: config.get(key) | ||
346 | 252 | mock_exists.return_value = True | ||
347 | 253 | mock_unit_get.return_value = '127.0.0.1' | ||
348 | 254 | mock_is_clustered.return_value = True | ||
349 | 255 | mock_resolve_address.return_value = '10.5.100.1' | ||
350 | 256 | mock_b64decode.return_value = 'decode_success' | ||
351 | 257 | |||
352 | 258 | mock_open.return_value.__enter__ = lambda s: s | ||
353 | 259 | mock_open.return_value.__exit__ = mock.Mock() | ||
354 | 260 | |||
355 | 261 | ctxt = context.ConsoleSSLContext()() | ||
356 | 262 | self.assertTrue(ctxt['ssl_only']) | ||
357 | 263 | self.assertEqual(ctxt['ssl_cert'], '/etc/nova/ssl/nova_cert.pem') | ||
358 | 264 | self.assertEqual(ctxt['ssl_key'], '/etc/nova/ssl/nova_key.pem') | ||
359 | 265 | self.assertEqual(ctxt['html5proxy_base_url'], | ||
360 | 266 | 'https://10.5.100.1:6082/spice_auto.html') | ||
361 | 267 | |||
362 | 268 | @mock.patch('__builtin__.open') | ||
363 | 269 | @mock.patch('os.path.exists') | ||
364 | 270 | @mock.patch.object(context, 'config') | ||
365 | 271 | @mock.patch.object(context, 'unit_get') | ||
366 | 272 | @mock.patch.object(context, 'is_clustered') | ||
367 | 273 | @mock.patch.object(context, 'resolve_address') | ||
368 | 274 | @mock.patch.object(context, 'b64decode') | ||
369 | 275 | def test_spice_html5_ssl_enabled_no_cluster(self, mock_b64decode, | ||
370 | 276 | mock_resolve_address, | ||
371 | 277 | mock_is_clustered, | ||
372 | 278 | mock_unit_get, | ||
373 | 279 | mock_config, mock_exists, | ||
374 | 280 | mock_open): | ||
375 | 281 | config = {'console-access-ssl-cert': 'LS0tLS1CRUdJTiBDRV', | ||
376 | 282 | 'console-access-ssl-key': 'LS0tLS1CRUdJTiBQUk', | ||
377 | 283 | 'console-access-protocol': 'spice'} | ||
378 | 284 | mock_config.side_effect = lambda key: config.get(key) | ||
379 | 285 | mock_exists.return_value = True | ||
380 | 286 | mock_unit_get.return_value = '10.5.0.1' | ||
381 | 287 | mock_is_clustered.return_value = False | ||
382 | 288 | mock_b64decode.return_value = 'decode_success' | ||
383 | 289 | |||
384 | 290 | mock_open.return_value.__enter__ = lambda s: s | ||
385 | 291 | mock_open.return_value.__exit__ = mock.Mock() | ||
386 | 292 | |||
387 | 293 | ctxt = context.ConsoleSSLContext()() | ||
388 | 294 | self.assertTrue(ctxt['ssl_only']) | ||
389 | 295 | self.assertEqual(ctxt['ssl_cert'], '/etc/nova/ssl/nova_cert.pem') | ||
390 | 296 | self.assertEqual(ctxt['ssl_key'], '/etc/nova/ssl/nova_key.pem') | ||
391 | 297 | self.assertEqual(ctxt['html5proxy_base_url'], | ||
392 | 298 | 'https://10.5.0.1:6082/spice_auto.html') | ||
393 | 151 | 299 | ||
394 | === modified file 'unit_tests/test_nova_cc_hooks.py' | |||
395 | --- unit_tests/test_nova_cc_hooks.py 2015-06-12 13:03:50 +0000 | |||
396 | +++ unit_tests/test_nova_cc_hooks.py 2015-07-24 10:07:27 +0000 | |||
397 | @@ -681,16 +681,14 @@ | |||
398 | 681 | } | 681 | } |
399 | 682 | self.assertEqual(_con_sets, console_settings) | 682 | self.assertEqual(_con_sets, console_settings) |
400 | 683 | 683 | ||
402 | 684 | @patch.object(hooks, 'canonical_url') | 684 | @patch.object(hooks, 'https') |
403 | 685 | @patch.object(utils, 'config') | 685 | @patch.object(utils, 'config') |
406 | 686 | def test_console_settings_explicit_ip(self, _utils_config, | 686 | def test_console_settings_explicit_ip(self, _utils_config, _https): |
405 | 687 | _canonical_url): | ||
407 | 688 | _utils_config.return_value = 'spice' | 687 | _utils_config.return_value = 'spice' |
408 | 688 | _https.return_value = False | ||
409 | 689 | _cc_public_host = "public-host" | 689 | _cc_public_host = "public-host" |
410 | 690 | _cc_private_host = "private-host" | ||
411 | 691 | self.test_config.set('console-proxy-ip', _cc_public_host) | 690 | self.test_config.set('console-proxy-ip', _cc_public_host) |
412 | 692 | _con_sets = hooks.console_settings() | 691 | _con_sets = hooks.console_settings() |
413 | 693 | _canonical_url.return_value = 'http://' + _cc_private_host | ||
414 | 694 | console_settings = { | 692 | console_settings = { |
415 | 695 | 'console_proxy_spice_address': 'http://%s:6082/spice_auto.html' % | 693 | 'console_proxy_spice_address': 'http://%s:6082/spice_auto.html' % |
416 | 696 | (_cc_public_host), | 694 | (_cc_public_host), |
417 | @@ -701,6 +699,25 @@ | |||
418 | 701 | } | 699 | } |
419 | 702 | self.assertEqual(_con_sets, console_settings) | 700 | self.assertEqual(_con_sets, console_settings) |
420 | 703 | 701 | ||
421 | 702 | @patch.object(hooks, 'https') | ||
422 | 703 | @patch.object(utils, 'config') | ||
423 | 704 | def test_console_settings_explicit_ip_with_https(self, _utils_config, | ||
424 | 705 | _https): | ||
425 | 706 | _utils_config.return_value = 'spice' | ||
426 | 707 | _https.return_value = True | ||
427 | 708 | _cc_public_host = "public-host" | ||
428 | 709 | self.test_config.set('console-proxy-ip', _cc_public_host) | ||
429 | 710 | _con_sets = hooks.console_settings() | ||
430 | 711 | console_settings = { | ||
431 | 712 | 'console_proxy_spice_address': 'https://%s:6082/spice_auto.html' % | ||
432 | 713 | (_cc_public_host), | ||
433 | 714 | 'console_proxy_spice_host': _cc_public_host, | ||
434 | 715 | 'console_proxy_spice_port': 6082, | ||
435 | 716 | 'console_access_protocol': 'spice', | ||
436 | 717 | 'console_keymap': 'en-us' | ||
437 | 718 | } | ||
438 | 719 | self.assertEqual(_con_sets, console_settings) | ||
439 | 720 | |||
440 | 704 | def test_conditional_neutron_migration(self): | 721 | def test_conditional_neutron_migration(self): |
441 | 705 | self.os_release.return_value = 'juno' | 722 | self.os_release.return_value = 'juno' |
442 | 706 | self.services.return_value = ['neutron-server'] | 723 | self.services.return_value = ['neutron-server'] |
charm_lint_check #6615 nova-cloud- controller- next for xianghui mp265496
LINT OK: passed
Build: http:// 10.245. 162.77: 8080/job/ charm_lint_ check/6615/