Merge lp:~bac/charms/trusty/openstack-dashboard/apache-slugs into lp:~yellow/charms/trusty/openstack-dashboard/dashboard-plugin
- Trusty Tahr (14.04)
- apache-slugs
- Merge into dashboard-plugin
Proposed by
Brad Crittenden
Status: | Merged |
---|---|
Merged at revision: | 86 |
Proposed branch: | lp:~bac/charms/trusty/openstack-dashboard/apache-slugs |
Merge into: | lp:~yellow/charms/trusty/openstack-dashboard/dashboard-plugin |
Diff against target: |
777 lines (+356/-24) 23 files modified
Makefile (+1/-2) actions.yaml (+2/-0) actions/openstack_upgrade.py (+34/-0) config.yaml (+31/-2) hooks/charmhelpers/contrib/openstack/utils.py (+48/-0) hooks/horizon_contexts.py (+68/-2) hooks/horizon_hooks.py (+11/-4) hooks/horizon_utils.py (+8/-7) hooks/install (+20/-0) metadata.yaml (+1/-0) templates/default (+2/-0) templates/default-ssl (+2/-0) templates/essex/local_settings.py (+2/-0) templates/folsom/local_settings.py (+2/-0) templates/grizzly/local_settings.py (+2/-0) templates/havana/local_settings.py (+2/-0) templates/icehouse/local_settings.py (+8/-0) templates/juno/local_settings.py (+8/-0) tests/00-setup (+1/-0) tests/tests.yaml (+1/-1) unit_tests/test_actions_openstack_upgrade.py (+53/-0) unit_tests/test_horizon_contexts.py (+39/-3) unit_tests/test_horizon_hooks.py (+10/-3) |
To merge this branch: | bzr merge lp:~bac/charms/trusty/openstack-dashboard/apache-slugs |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jay R. Wren (community) | Approve | ||
j.c.sackett (community) | Approve | ||
Review via email:
|
Commit message
Description of the change
Allow the ability to add controls to the end http and https configurations. Useful for things like rewrite stanzas.
To post a comment you must log in.
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Brad Crittenden (bac) wrote : | # |
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
j.c.sackett (jcsackett) wrote : | # |
LGTM, thanks Brad.
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'Makefile' |
2 | --- Makefile 2015-08-22 04:13:34 +0000 |
3 | +++ Makefile 2015-10-14 14:39:53 +0000 |
4 | @@ -9,11 +9,10 @@ |
5 | test: |
6 | @# Bundletester expects unit tests here. |
7 | @echo Starting tests... |
8 | - @$(PYTHON) /usr/bin/nosetests --nologcapture --with-coverage unit_tests |
9 | + @$(PYTHON) /usr/bin/nosetests -v --nologcapture --with-coverage unit_tests |
10 | |
11 | functional_test: |
12 | @echo Starting Amulet tests... |
13 | - # https://bugs.launchpad.net/amulet/+bug/1320357 |
14 | @juju test -v -p AMULET_HTTP_PROXY,AMULET_OS_VIP --timeout 2700 |
15 | |
16 | bin/charm_helpers_sync.py: |
17 | |
18 | === modified file 'actions.yaml' |
19 | --- actions.yaml 2015-04-07 13:58:41 +0000 |
20 | +++ actions.yaml 2015-10-14 14:39:53 +0000 |
21 | @@ -1,2 +1,4 @@ |
22 | git-reinstall: |
23 | description: Reinstall openstack-dashboard from the openstack-origin-git repositories. |
24 | +openstack-upgrade: |
25 | + description: Perform openstack upgrades. Config option action-managed-upgrade must be set to True. |
26 | |
27 | === added symlink 'actions/openstack-upgrade' |
28 | === target is u'openstack_upgrade.py' |
29 | === added file 'actions/openstack_upgrade.py' |
30 | --- actions/openstack_upgrade.py 1970-01-01 00:00:00 +0000 |
31 | +++ actions/openstack_upgrade.py 2015-10-14 14:39:53 +0000 |
32 | @@ -0,0 +1,34 @@ |
33 | +#!/usr/bin/python |
34 | +import sys |
35 | + |
36 | +sys.path.append('hooks/') |
37 | + |
38 | +from charmhelpers.contrib.openstack.utils import ( |
39 | + do_action_openstack_upgrade, |
40 | +) |
41 | + |
42 | +from horizon_utils import ( |
43 | + do_openstack_upgrade, |
44 | +) |
45 | + |
46 | +from horizon_hooks import ( |
47 | + config_changed, |
48 | + CONFIGS, |
49 | +) |
50 | + |
51 | + |
52 | +def openstack_upgrade(): |
53 | + """Upgrade packages to config-set Openstack version. |
54 | + |
55 | + If the charm was installed from source we cannot upgrade it. |
56 | + For backwards compatibility a config flag must be set for this |
57 | + code to run, otherwise a full service level upgrade will fire |
58 | + on config-changed.""" |
59 | + |
60 | + if do_action_openstack_upgrade('openstack-dashboard', |
61 | + do_openstack_upgrade, |
62 | + CONFIGS): |
63 | + config_changed() |
64 | + |
65 | +if __name__ == '__main__': |
66 | + openstack_upgrade() |
67 | |
68 | === modified file 'config.yaml' |
69 | --- config.yaml 2015-07-10 14:18:48 +0000 |
70 | +++ config.yaml 2015-10-14 14:39:53 +0000 |
71 | @@ -153,6 +153,14 @@ |
72 | In order for this charm to function correctly, the privacy extension |
73 | must be disabled and a non-temporary address must be |
74 | configured/available on your network interface. |
75 | + endpoint-type: |
76 | + type: string |
77 | + default: |
78 | + description: | |
79 | + Specifies the endpoint types to use for endpoints in the Keystone |
80 | + service catalog. Valid values are 'publicURL', 'internalURL', |
81 | + and 'adminURL'. Both the primary and secondary endpoint types can |
82 | + be specified by providing multiple comma delimited values. |
83 | nagios_context: |
84 | default: "juju" |
85 | type: string |
86 | @@ -163,7 +171,7 @@ |
87 | . |
88 | juju-postgresql-0 |
89 | . |
90 | - If you're running multiple environments with the same services in them |
91 | + If you are running multiple environments with the same services in them |
92 | this allows you to differentiate between them. |
93 | nagios_check_http_params: |
94 | default: "-H localhost -I 127.0.0.1 -u '/' -e 200,301,302" |
95 | @@ -175,4 +183,25 @@ |
96 | description: | |
97 | A comma-separated list of nagios servicegroups. If left empty, the |
98 | nagios_context will be used as the servicegroup. |
99 | - |
100 | + action-managed-upgrade: |
101 | + type: boolean |
102 | + default: False |
103 | + description: | |
104 | + If True enables openstack upgrades for this charm via juju actions. |
105 | + You will still need to set openstack-origin to the new repository but |
106 | + instead of an upgrade running automatically across all units, it will |
107 | + wait for you to execute the openstack-upgrade action for this charm on |
108 | + each unit. If False it will revert to existing behavior of upgrading |
109 | + all units on config change. |
110 | + apache_http_addendum: |
111 | + type: string |
112 | + default: '' |
113 | + description: | |
114 | + Extra stanzas to be inserted into the HTTP virtual host configuration. |
115 | + May be used to specify rewrite rules, for example. |
116 | + apache_https_addendum: |
117 | + type: string |
118 | + default: '' |
119 | + description: | |
120 | + Extra stanzas to be inserted into the HTTPS virtual host configuration. |
121 | + May be used to specify rewrite rules, for example. |
122 | |
123 | === modified file 'hooks/charmhelpers/contrib/openstack/utils.py' |
124 | --- hooks/charmhelpers/contrib/openstack/utils.py 2015-09-04 13:59:26 +0000 |
125 | +++ hooks/charmhelpers/contrib/openstack/utils.py 2015-10-14 14:39:53 +0000 |
126 | @@ -25,6 +25,7 @@ |
127 | import re |
128 | |
129 | import six |
130 | +import traceback |
131 | import yaml |
132 | |
133 | from charmhelpers.contrib.network import ip |
134 | @@ -34,6 +35,8 @@ |
135 | ) |
136 | |
137 | from charmhelpers.core.hookenv import ( |
138 | + action_fail, |
139 | + action_set, |
140 | config, |
141 | log as juju_log, |
142 | charm_dir, |
143 | @@ -114,6 +117,7 @@ |
144 | ('2.2.1', 'kilo'), |
145 | ('2.2.2', 'kilo'), |
146 | ('2.3.0', 'liberty'), |
147 | + ('2.4.0', 'liberty'), |
148 | ]) |
149 | |
150 | # >= Liberty version->codename mapping |
151 | @@ -748,3 +752,47 @@ |
152 | return projects[key] |
153 | |
154 | return None |
155 | + |
156 | + |
157 | +def do_action_openstack_upgrade(package, upgrade_callback, configs): |
158 | + """Perform action-managed OpenStack upgrade. |
159 | + |
160 | + Upgrades packages to the configured openstack-origin version and sets |
161 | + the corresponding action status as a result. |
162 | + |
163 | + If the charm was installed from source we cannot upgrade it. |
164 | + For backwards compatibility a config flag (action-managed-upgrade) must |
165 | + be set for this code to run, otherwise a full service level upgrade will |
166 | + fire on config-changed. |
167 | + |
168 | + @param package: package name for determining if upgrade available |
169 | + @param upgrade_callback: function callback to charm's upgrade function |
170 | + @param configs: templating object derived from OSConfigRenderer class |
171 | + |
172 | + @return: True if upgrade successful; False if upgrade failed or skipped |
173 | + """ |
174 | + ret = False |
175 | + |
176 | + if git_install_requested(): |
177 | + action_set({'outcome': 'installed from source, skipped upgrade.'}) |
178 | + else: |
179 | + if openstack_upgrade_available(package): |
180 | + if config('action-managed-upgrade'): |
181 | + juju_log('Upgrading OpenStack release') |
182 | + |
183 | + try: |
184 | + upgrade_callback(configs=configs) |
185 | + action_set({'outcome': 'success, upgrade completed.'}) |
186 | + ret = True |
187 | + except: |
188 | + action_set({'outcome': 'upgrade failed, see traceback.'}) |
189 | + action_set({'traceback': traceback.format_exc()}) |
190 | + action_fail('do_openstack_upgrade resulted in an ' |
191 | + 'unexpected error') |
192 | + else: |
193 | + action_set({'outcome': 'action-managed-upgrade config is ' |
194 | + 'False, skipped upgrade.'}) |
195 | + else: |
196 | + action_set({'outcome': 'no upgrade available.'}) |
197 | + |
198 | + return ret |
199 | |
200 | === added symlink 'hooks/dashboard-plugin-relation-changed' |
201 | === target is u'horizon_hooks.py' |
202 | === added symlink 'hooks/dashboard-plugin-relation-joined' |
203 | === target is u'horizon_hooks.py' |
204 | === removed symlink 'hooks/dashboard-plugin-relation-joined' |
205 | === target was u'horizon_hooks.py' |
206 | === modified file 'hooks/horizon_contexts.py' |
207 | --- hooks/horizon_contexts.py 2015-04-09 14:56:00 +0000 |
208 | +++ hooks/horizon_contexts.py 2015-10-14 14:39:53 +0000 |
209 | @@ -6,7 +6,8 @@ |
210 | relation_get, |
211 | local_unit, |
212 | unit_get, |
213 | - log |
214 | + log, |
215 | + ERROR, |
216 | ) |
217 | from charmhelpers.contrib.openstack.context import ( |
218 | OSContextGenerator, |
219 | @@ -28,6 +29,12 @@ |
220 | from base64 import b64decode |
221 | import os |
222 | |
223 | +VALID_ENDPOINT_TYPES = { |
224 | + 'PUBLICURL': 'publicURL', |
225 | + 'INTERNALURL': 'internalURL', |
226 | + 'ADMINURL': 'adminURL', |
227 | +} |
228 | + |
229 | |
230 | class HorizonHAProxyContext(HAProxyContext): |
231 | def __call__(self): |
232 | @@ -69,6 +76,22 @@ |
233 | class IdentityServiceContext(OSContextGenerator): |
234 | interfaces = ['identity-service'] |
235 | |
236 | + def normalize(self, endpoint_type): |
237 | + """Normalizes the endpoint type values. |
238 | + |
239 | + :param endpoint_type (string): the endpoint type to normalize. |
240 | + :raises: Exception if the endpoint type is not valid. |
241 | + :return (string): the normalized form of the endpoint type. |
242 | + """ |
243 | + normalized_form = VALID_ENDPOINT_TYPES.get(endpoint_type.upper(), None) |
244 | + if not normalized_form: |
245 | + msg = ('Endpoint type specified %s is not a valid' |
246 | + ' endpoint type' % endpoint_type) |
247 | + log(msg, ERROR) |
248 | + raise Exception(msg) |
249 | + |
250 | + return normalized_form |
251 | + |
252 | def __call__(self): |
253 | log('Generating template context for identity-service') |
254 | ctxt = {} |
255 | @@ -106,6 +129,21 @@ |
256 | avail_regions = map(lambda r: {'endpoint': r[0], 'title': r[1]}, |
257 | regions) |
258 | ctxt['regions'] = sorted(avail_regions) |
259 | + |
260 | + # Allow the endpoint types to be specified via a config parameter. |
261 | + # The config parameter accepts either: |
262 | + # 1. a single endpoint type to be specified, in which case the |
263 | + # primary endpoint is configured |
264 | + # 2. a list of endpoint types, in which case the primary endpoint |
265 | + # is taken as the first entry and the secondary endpoint is |
266 | + # taken as the second entry. All subsequent entries are ignored. |
267 | + ep_types = config('endpoint-type') |
268 | + if ep_types: |
269 | + ep_types = [self.normalize(e) for e in ep_types.split(',')] |
270 | + ctxt['primary_endpoint'] = ep_types[0] |
271 | + if len(ep_types) > 1: |
272 | + ctxt['secondary_endpoint'] = ep_types[1] |
273 | + |
274 | return ctxt |
275 | |
276 | |
277 | @@ -134,7 +172,8 @@ |
278 | ''' Grab cert and key from configuraton for SSL config ''' |
279 | ctxt = { |
280 | 'http_port': 70, |
281 | - 'https_port': 433 |
282 | + 'https_port': 433, |
283 | + 'apache_http_addendum': config("apache_http_addendum"), |
284 | } |
285 | return ctxt |
286 | |
287 | @@ -162,6 +201,8 @@ |
288 | ctxt = { |
289 | 'ssl_configured': False, |
290 | } |
291 | + ctxt['apache_https_addendum'] = config("apache_https_addendum") |
292 | + |
293 | return ctxt |
294 | |
295 | |
296 | @@ -172,3 +213,28 @@ |
297 | 'disable_router': False if config('profile') in ['cisco'] else True |
298 | } |
299 | return ctxt |
300 | + |
301 | + |
302 | +class LocalSettingsContext(OSContextGenerator): |
303 | + def __call__(self): |
304 | + ''' Additional config stanzas to be appended to local_settings.py ''' |
305 | + |
306 | + relations = [] |
307 | + |
308 | + for rid in relation_ids("plugin"): |
309 | + try: |
310 | + unit = related_units(rid)[0] |
311 | + except IndexError: |
312 | + pass |
313 | + else: |
314 | + rdata = relation_get(unit=unit, rid=rid) |
315 | + if set(('local-settings', 'priority')) <= set(rdata.keys()): |
316 | + relations.append((unit, rdata)) |
317 | + |
318 | + ctxt = { |
319 | + 'settings': [ |
320 | + '# {0}\n{1}'.format(u, rd['local-settings']) |
321 | + for u, rd in sorted(relations, |
322 | + key=lambda r: r[1]['priority'])] |
323 | + } |
324 | + return ctxt |
325 | |
326 | === modified file 'hooks/horizon_hooks.py' |
327 | --- hooks/horizon_hooks.py 2015-09-03 19:18:51 +0000 |
328 | +++ hooks/horizon_hooks.py 2015-10-14 14:39:53 +0000 |
329 | @@ -58,7 +58,7 @@ |
330 | CONFIGS = register_configs() |
331 | |
332 | |
333 | -@hooks.hook('install') |
334 | +@hooks.hook('install.real') |
335 | def install(): |
336 | execd_preinstall() |
337 | configure_installation_source(config('openstack-origin')) |
338 | @@ -106,7 +106,7 @@ |
339 | if git_install_requested(): |
340 | if config_value_changed('openstack-origin-git'): |
341 | git_install(config('openstack-origin-git')) |
342 | - else: |
343 | + elif not config('action-managed-upgrade'): |
344 | if openstack_upgrade_available('openstack-dashboard'): |
345 | do_openstack_upgrade(configs=CONFIGS) |
346 | |
347 | @@ -247,16 +247,23 @@ |
348 | |
349 | |
350 | @hooks.hook('dashboard-plugin-relation-joined') |
351 | -def update_dashboard_plugin(rel_id=None): |
352 | +def plugin_relation_joined(rel_id=None): |
353 | if git_install_requested(): |
354 | bin_path = git_pip_venv_dir(config('openstack-origin-git')) |
355 | else: |
356 | bin_path = '/usr/bin' |
357 | - relation_set(relation_id=rel_id, |
358 | + relation_set(release=os_release("openstack-dashboard"), |
359 | + relation_id=rel_id, |
360 | bin_path=bin_path, |
361 | openstack_dir=INSTALL_DIR) |
362 | |
363 | |
364 | +@hooks.hook('dashboard-plugin-relation-changed') |
365 | +@restart_on_change(restart_map()) |
366 | +def update_plugin_config(): |
367 | + CONFIGS.write(LOCAL_SETTINGS) |
368 | + |
369 | + |
370 | def main(): |
371 | try: |
372 | hooks.execute(sys.argv) |
373 | |
374 | === modified file 'hooks/horizon_utils.py' |
375 | --- hooks/horizon_utils.py 2015-09-03 19:18:51 +0000 |
376 | +++ hooks/horizon_utils.py 2015-10-14 14:39:53 +0000 |
377 | @@ -101,7 +101,8 @@ |
378 | (LOCAL_SETTINGS, { |
379 | 'hook_contexts': [horizon_contexts.HorizonContext(), |
380 | horizon_contexts.IdentityServiceContext(), |
381 | - context.SyslogContext()], |
382 | + context.SyslogContext(), |
383 | + horizon_contexts.LocalSettingsContext()], |
384 | 'services': ['apache2'] |
385 | }), |
386 | (APACHE_CONF, { |
387 | @@ -262,12 +263,12 @@ |
388 | raise Exception("IPv6 is not supported in the charms for Ubuntu " |
389 | "versions less than Trusty 14.04") |
390 | |
391 | - # NOTE(xianghui): Need to install haproxy(1.5.3) from trusty-backports |
392 | - # to support ipv6 address, so check is required to make sure not |
393 | - # breaking other versions, IPv6 only support for >= Trusty |
394 | - if ubuntu_rel == 'trusty': |
395 | - add_source('deb http://archive.ubuntu.com/ubuntu trusty-backports' |
396 | - ' main') |
397 | + # Need haproxy >= 1.5.3 for ipv6 so for Trusty if we are <= Kilo we need to |
398 | + # use trusty-backports otherwise we can use the UCA. |
399 | + os_pkg = 'openstack-dashboard' |
400 | + if ubuntu_rel == 'trusty' and os_release(os_pkg) < 'liberty': |
401 | + add_source('deb http://archive.ubuntu.com/ubuntu trusty-backports ' |
402 | + 'main') |
403 | apt_update() |
404 | apt_install('haproxy/trusty-backports', fatal=True) |
405 | |
406 | |
407 | === modified symlink 'hooks/install' (properties changed: -x to +x) |
408 | === target was u'horizon_hooks.py' |
409 | --- hooks/install 1970-01-01 00:00:00 +0000 |
410 | +++ hooks/install 2015-10-14 14:39:53 +0000 |
411 | @@ -0,0 +1,20 @@ |
412 | +#!/bin/bash |
413 | +# Wrapper to deal with newer Ubuntu versions that don't have py2 installed |
414 | +# by default. |
415 | + |
416 | +declare -a DEPS=('apt' 'netaddr' 'netifaces' 'pip' 'yaml') |
417 | + |
418 | +check_and_install() { |
419 | + pkg="${1}-${2}" |
420 | + if ! dpkg -s ${pkg} 2>&1 > /dev/null; then |
421 | + apt-get -y install ${pkg} |
422 | + fi |
423 | +} |
424 | + |
425 | +PYTHON="python" |
426 | + |
427 | +for dep in ${DEPS[@]}; do |
428 | + check_and_install ${PYTHON} ${dep} |
429 | +done |
430 | + |
431 | +exec ./hooks/install.real |
432 | |
433 | === added symlink 'hooks/install.real' |
434 | === target is u'horizon_hooks.py' |
435 | === modified file 'metadata.yaml' |
436 | --- metadata.yaml 2015-09-10 20:38:16 +0000 |
437 | +++ metadata.yaml 2015-10-14 14:39:53 +0000 |
438 | @@ -15,6 +15,7 @@ |
439 | interface: http |
440 | dashboard-plugin: |
441 | interface: dashboard-plugin |
442 | + scope: container |
443 | requires: |
444 | identity-service: |
445 | interface: keystone |
446 | |
447 | === modified file 'templates/default' |
448 | --- templates/default 2013-07-15 16:25:46 +0000 |
449 | +++ templates/default 2015-10-14 14:39:53 +0000 |
450 | @@ -29,4 +29,6 @@ |
451 | |
452 | CustomLog ${APACHE_LOG_DIR}/access.log combined |
453 | |
454 | +{{ apache_http_addendum }} |
455 | + |
456 | </VirtualHost> |
457 | |
458 | === modified file 'templates/default-ssl' |
459 | --- templates/default-ssl 2013-07-15 16:25:46 +0000 |
460 | +++ templates/default-ssl 2015-10-14 14:39:53 +0000 |
461 | @@ -46,5 +46,7 @@ |
462 | downgrade-1.0 force-response-1.0 |
463 | BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown |
464 | |
465 | +{{ apache_https_addendum }} |
466 | + |
467 | </VirtualHost> |
468 | </IfModule> |
469 | |
470 | === modified file 'templates/essex/local_settings.py' |
471 | --- templates/essex/local_settings.py 2014-02-27 10:07:57 +0000 |
472 | +++ templates/essex/local_settings.py 2015-10-14 14:39:53 +0000 |
473 | @@ -118,3 +118,5 @@ |
474 | } |
475 | } |
476 | } |
477 | + |
478 | +{{ settings|join('\n\n') }} |
479 | |
480 | === modified file 'templates/folsom/local_settings.py' |
481 | --- templates/folsom/local_settings.py 2014-05-28 16:05:37 +0000 |
482 | +++ templates/folsom/local_settings.py 2015-10-14 14:39:53 +0000 |
483 | @@ -167,3 +167,5 @@ |
484 | # offline compression by default. To enable online compression, install |
485 | # the node-less package and enable the following option. |
486 | COMPRESS_OFFLINE = {{ compress_offline }} |
487 | + |
488 | +{{ settings|join('\n\n') }} |
489 | \ No newline at end of file |
490 | |
491 | === modified file 'templates/grizzly/local_settings.py' |
492 | --- templates/grizzly/local_settings.py 2014-05-28 16:05:37 +0000 |
493 | +++ templates/grizzly/local_settings.py 2015-10-14 14:39:53 +0000 |
494 | @@ -263,3 +263,5 @@ |
495 | } |
496 | } |
497 | } |
498 | + |
499 | +{{ settings|join('\n\n') }} |
500 | |
501 | === modified file 'templates/havana/local_settings.py' |
502 | --- templates/havana/local_settings.py 2014-07-22 07:18:55 +0000 |
503 | +++ templates/havana/local_settings.py 2015-10-14 14:39:53 +0000 |
504 | @@ -483,3 +483,5 @@ |
505 | # installations should have this set accordingly. For more information |
506 | # see https://docs.djangoproject.com/en/dev/ref/settings/. |
507 | ALLOWED_HOSTS = '*' |
508 | + |
509 | +{{ settings|join('\n\n') }} |
510 | \ No newline at end of file |
511 | |
512 | === modified file 'templates/icehouse/local_settings.py' |
513 | --- templates/icehouse/local_settings.py 2014-12-01 23:45:41 +0000 |
514 | +++ templates/icehouse/local_settings.py 2015-10-14 14:39:53 +0000 |
515 | @@ -212,6 +212,9 @@ |
516 | # in the Keystone service catalog. Use this setting when Horizon is running |
517 | # external to the OpenStack environment. The default is 'publicURL'. |
518 | #OPENSTACK_ENDPOINT_TYPE = "publicURL" |
519 | +{% if primary_endpoint -%} |
520 | +OPENSTACK_ENDPOINT_TYPE = {{ primary_endpoint }} |
521 | +{% endif -%} |
522 | |
523 | # SECONDARY_ENDPOINT_TYPE specifies the fallback endpoint type to use in the |
524 | # case that OPENSTACK_ENDPOINT_TYPE is not present in the endpoints |
525 | @@ -219,6 +222,9 @@ |
526 | # external to the OpenStack environment. The default is None. This |
527 | # value should differ from OPENSTACK_ENDPOINT_TYPE if used. |
528 | #SECONDARY_ENDPOINT_TYPE = "publicURL" |
529 | +{% if secondary_endpoint -%} |
530 | +SECONDARY_ENDPOINT_TYPE = {{ secondary_endpoint }} |
531 | +{% endif -%} |
532 | |
533 | # The number of objects (Swift containers/objects or images) to display |
534 | # on a single page before providing a paging element (a "more" link) |
535 | @@ -514,3 +520,5 @@ |
536 | # installations should have this set accordingly. For more information |
537 | # see https://docs.djangoproject.com/en/dev/ref/settings/. |
538 | ALLOWED_HOSTS = '*' |
539 | + |
540 | +{{ settings|join('\n\n') }} |
541 | \ No newline at end of file |
542 | |
543 | === modified file 'templates/juno/local_settings.py' |
544 | --- templates/juno/local_settings.py 2014-12-01 23:45:41 +0000 |
545 | +++ templates/juno/local_settings.py 2015-10-14 14:39:53 +0000 |
546 | @@ -250,6 +250,9 @@ |
547 | # in the Keystone service catalog. Use this setting when Horizon is running |
548 | # external to the OpenStack environment. The default is 'publicURL'. |
549 | #OPENSTACK_ENDPOINT_TYPE = "publicURL" |
550 | +{% if primary_endpoint -%} |
551 | +OPENSTACK_ENDPOINT_TYPE = {{ primary_endpoint }} |
552 | +{% endif -%} |
553 | |
554 | # SECONDARY_ENDPOINT_TYPE specifies the fallback endpoint type to use in the |
555 | # case that OPENSTACK_ENDPOINT_TYPE is not present in the endpoints |
556 | @@ -257,6 +260,9 @@ |
557 | # external to the OpenStack environment. The default is None. This |
558 | # value should differ from OPENSTACK_ENDPOINT_TYPE if used. |
559 | #SECONDARY_ENDPOINT_TYPE = "publicURL" |
560 | +{% if secondary_endpoint -%} |
561 | +SECONDARY_ENDPOINT_TYPE = {{ secondary_endpoint }} |
562 | +{% endif -%} |
563 | |
564 | # The number of objects (Swift containers/objects or images) to display |
565 | # on a single page before providing a paging element (a "more" link) |
566 | @@ -619,3 +625,5 @@ |
567 | # installations should have this set accordingly. For more information |
568 | # see https://docs.djangoproject.com/en/dev/ref/settings/. |
569 | ALLOWED_HOSTS = '*' |
570 | + |
571 | +{{ settings|join('\n\n') }} |
572 | \ No newline at end of file |
573 | |
574 | === modified file 'tests/00-setup' |
575 | --- tests/00-setup 2015-08-21 18:42:43 +0000 |
576 | +++ tests/00-setup 2015-10-14 14:39:53 +0000 |
577 | @@ -5,6 +5,7 @@ |
578 | sudo add-apt-repository --yes ppa:juju/stable |
579 | sudo apt-get update --yes |
580 | sudo apt-get install --yes amulet \ |
581 | + distro-info-data \ |
582 | python-cinderclient \ |
583 | python-distro-info \ |
584 | python-glanceclient \ |
585 | |
586 | === modified file 'tests/tests.yaml' |
587 | --- tests/tests.yaml 2015-08-21 18:42:43 +0000 |
588 | +++ tests/tests.yaml 2015-10-14 14:39:53 +0000 |
589 | @@ -8,7 +8,7 @@ |
590 | - ppa:juju/stable |
591 | packages: |
592 | - amulet |
593 | - - python-amulet |
594 | + - distro-info-data |
595 | - python-cinderclient |
596 | - python-distro-info |
597 | - python-glanceclient |
598 | |
599 | === added file 'unit_tests/test_actions_openstack_upgrade.py' |
600 | --- unit_tests/test_actions_openstack_upgrade.py 1970-01-01 00:00:00 +0000 |
601 | +++ unit_tests/test_actions_openstack_upgrade.py 2015-10-14 14:39:53 +0000 |
602 | @@ -0,0 +1,53 @@ |
603 | +from mock import patch |
604 | +import os |
605 | + |
606 | +os.environ['JUJU_UNIT_NAME'] = 'openstack-dashboard' |
607 | + |
608 | +with patch('horizon_utils.register_configs') as register_configs: |
609 | + import openstack_upgrade |
610 | + |
611 | +from test_utils import ( |
612 | + CharmTestCase |
613 | +) |
614 | + |
615 | +TO_PATCH = [ |
616 | + 'do_openstack_upgrade', |
617 | + 'config_changed', |
618 | +] |
619 | + |
620 | + |
621 | +class TestHorizonUpgradeActions(CharmTestCase): |
622 | + |
623 | + def setUp(self): |
624 | + super(TestHorizonUpgradeActions, self).setUp(openstack_upgrade, |
625 | + TO_PATCH) |
626 | + |
627 | + @patch('charmhelpers.contrib.openstack.utils.config') |
628 | + @patch('charmhelpers.contrib.openstack.utils.action_set') |
629 | + @patch('charmhelpers.contrib.openstack.utils.git_install_requested') |
630 | + @patch('charmhelpers.contrib.openstack.utils.openstack_upgrade_available') |
631 | + def test_openstack_upgrade_true(self, upgrade_avail, git_requested, |
632 | + action_set, config): |
633 | + git_requested.return_value = False |
634 | + upgrade_avail.return_value = True |
635 | + config.return_value = True |
636 | + |
637 | + openstack_upgrade.openstack_upgrade() |
638 | + |
639 | + self.assertTrue(self.do_openstack_upgrade.called) |
640 | + self.assertTrue(self.config_changed.called) |
641 | + |
642 | + @patch('charmhelpers.contrib.openstack.utils.config') |
643 | + @patch('charmhelpers.contrib.openstack.utils.action_set') |
644 | + @patch('charmhelpers.contrib.openstack.utils.git_install_requested') |
645 | + @patch('charmhelpers.contrib.openstack.utils.openstack_upgrade_available') |
646 | + def test_openstack_upgrade_false(self, upgrade_avail, git_requested, |
647 | + action_set, config): |
648 | + git_requested.return_value = False |
649 | + upgrade_avail.return_value = True |
650 | + config.return_value = False |
651 | + |
652 | + openstack_upgrade.openstack_upgrade() |
653 | + |
654 | + self.assertFalse(self.do_openstack_upgrade.called) |
655 | + self.assertFalse(self.config_changed.called) |
656 | |
657 | === modified file 'unit_tests/test_horizon_contexts.py' |
658 | --- unit_tests/test_horizon_contexts.py 2015-04-09 14:34:44 +0000 |
659 | +++ unit_tests/test_horizon_contexts.py 2015-10-14 14:39:53 +0000 |
660 | @@ -47,19 +47,23 @@ |
661 | self.pwgen.return_value = "secret" |
662 | |
663 | def test_Apachecontext(self): |
664 | + self.test_config.set('apache_http_addendum', 'RewriteEngine on') |
665 | self.assertEquals(horizon_contexts.ApacheContext()(), |
666 | - {'http_port': 70, 'https_port': 433}) |
667 | + {'http_port': 70, 'https_port': 433, |
668 | + 'apache_http_addendum': 'RewriteEngine on'}) |
669 | |
670 | @patch.object(horizon_contexts, 'get_ca_cert', lambda: None) |
671 | @patch('os.chmod') |
672 | def test_ApacheSSLContext_enabled(self, _chmod): |
673 | self.get_cert.return_value = ('cert', 'key') |
674 | self.b64decode.side_effect = ['cert', 'key'] |
675 | + self.test_config.set('apache_https_addendum', 'RewriteEngine off') |
676 | with patch_open() as (_open, _file): |
677 | self.assertEquals(horizon_contexts.ApacheSSLContext()(), |
678 | {'ssl_configured': True, |
679 | 'ssl_cert': '/etc/ssl/certs/dashboard.cert', |
680 | - 'ssl_key': '/etc/ssl/private/dashboard.key'}) |
681 | + 'ssl_key': '/etc/ssl/private/dashboard.key', |
682 | + 'apache_https_addendum': 'RewriteEngine off'}) |
683 | _open.assert_has_calls([ |
684 | call('/etc/ssl/certs/dashboard.cert', 'w'), |
685 | call('/etc/ssl/private/dashboard.key', 'w') |
686 | @@ -75,7 +79,8 @@ |
687 | def test_ApacheSSLContext_disabled(self): |
688 | self.get_cert.return_value = (None, None) |
689 | self.assertEquals(horizon_contexts.ApacheSSLContext()(), |
690 | - {'ssl_configured': False}) |
691 | + {'ssl_configured': False, |
692 | + 'apache_https_addendum': ''}) |
693 | |
694 | def test_HorizonContext_defaults(self): |
695 | self.assertEquals(horizon_contexts.HorizonContext()(), |
696 | @@ -212,6 +217,22 @@ |
697 | {'endpoint': 'http://foo:5000/v2.0', |
698 | 'title': 'regionTwo'}]}) |
699 | |
700 | + def test_IdentityServiceContext_endpoint_type(self): |
701 | + self.test_config.set('endpoint-type', 'internalURL') |
702 | + self.assertEqual(horizon_contexts.IdentityServiceContext()(), |
703 | + {'primary_endpoint': 'internalURL'}) |
704 | + |
705 | + def test_IdentityServiceContext_multi_endpoint_types(self): |
706 | + self.test_config.set('endpoint-type', 'internalURL,publicURL') |
707 | + self.assertEqual(horizon_contexts.IdentityServiceContext()(), |
708 | + {'primary_endpoint': 'internalURL', |
709 | + 'secondary_endpoint': 'publicURL'}) |
710 | + |
711 | + def test_IdentityServiceContext_invalid_endpoint_type(self): |
712 | + self.test_config.set('endpoint-type', 'this_is_bad') |
713 | + with self.assertRaises(Exception): |
714 | + horizon_contexts.IdentityServiceContext()() |
715 | + |
716 | def test_HorizonHAProxyContext_no_cluster(self): |
717 | self.relation_ids.return_value = [] |
718 | self.local_unit.return_value = 'openstack-dashboard/0' |
719 | @@ -251,3 +272,18 @@ |
720 | self.test_config.set('profile', None) |
721 | self.assertEquals(horizon_contexts.RouterSettingContext()(), |
722 | {'disable_router': True, }) |
723 | + |
724 | + def test_LocalSettingsContext(self): |
725 | + self.relation_ids.return_value = ['plugin:0', 'plugin-too:0'] |
726 | + self.related_units.side_effect = [['horizon-plugin/0'], |
727 | + ['horizon-plugin-too/0']] |
728 | + self.relation_get.side_effect = [{'priority': 99, |
729 | + 'local-settings': 'FOO = True'}, |
730 | + {'priority': 60, |
731 | + 'local-settings': 'BAR = False'}] |
732 | + |
733 | + self.assertEquals(horizon_contexts.LocalSettingsContext()(), |
734 | + {'settings': ['# horizon-plugin-too/0\n' |
735 | + 'BAR = False', |
736 | + '# horizon-plugin/0\n' |
737 | + 'FOO = True']}) |
738 | |
739 | === modified file 'unit_tests/test_horizon_hooks.py' |
740 | --- unit_tests/test_horizon_hooks.py 2015-09-04 15:16:58 +0000 |
741 | +++ unit_tests/test_horizon_hooks.py 2015-10-14 14:39:53 +0000 |
742 | @@ -308,25 +308,32 @@ |
743 | self._call_hook('website-relation-joined') |
744 | self.relation_set.assert_called_with(port=70, hostname='192.168.1.1') |
745 | |
746 | + @patch.object(hooks, 'os_release') |
747 | @patch.object(hooks, 'git_install_requested') |
748 | - def test_dashboard_config_joined_not_git(self, _git_requested): |
749 | + def test_dashboard_config_joined_not_git( |
750 | + self, _git_requested, _os_release): |
751 | _git_requested.return_value = False |
752 | + _os_release.return_value = 'vivid' |
753 | self._call_hook('dashboard-plugin-relation-joined') |
754 | self.relation_set.assert_called_with( |
755 | + release='vivid', |
756 | bin_path='/usr/bin', |
757 | openstack_dir='/usr/share/openstack-dashboard', |
758 | relation_id=None |
759 | ) |
760 | |
761 | + @patch.object(hooks, 'os_release') |
762 | @patch.object(hooks, 'git_pip_venv_dir') |
763 | @patch.object(hooks, 'git_install_requested') |
764 | - def test_dashboard_config_joined_git(self, _git_requested, |
765 | - _git_pip_venv_dir): |
766 | + def test_dashboard_config_joined_git( |
767 | + self, _git_requested, _git_pip_venv_dir, _os_release): |
768 | expected_bin_path = '/mnt/fuji/venv' |
769 | _git_requested.return_value = True |
770 | _git_pip_venv_dir.return_value = expected_bin_path |
771 | + _os_release.return_value = 'wily' |
772 | self._call_hook('dashboard-plugin-relation-joined') |
773 | self.relation_set.assert_called_with( |
774 | + release='wily', |
775 | bin_path=expected_bin_path, |
776 | openstack_dir='/usr/share/openstack-dashboard', |
777 | relation_id=None |
This branch was started based on the 'next' version of the openstack- dashboard, so it brings our up-to-date with the latest.