Merge lp:~bac/charms/trusty/openstack-dashboard/apache-slugs into lp:~yellow/charms/trusty/openstack-dashboard/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
Reviewer Review Type Date Requested Status
Jay R. Wren (community) Approve
j.c.sackett (community) Approve
Review via email: mp+274411@code.launchpad.net

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
Brad Crittenden (bac) wrote :

This branch was started based on the 'next' version of the openstack-dashboard, so it brings our up-to-date with the latest.

Revision history for this message
j.c.sackett (jcsackett) wrote :

LGTM, thanks Brad.

review: Approve
Revision history for this message
Jay R. Wren (evarlast) wrote :

LGTM.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Makefile'
--- Makefile 2015-08-22 04:13:34 +0000
+++ Makefile 2015-10-14 14:39:53 +0000
@@ -9,11 +9,10 @@
9test:9test:
10 @# Bundletester expects unit tests here.10 @# Bundletester expects unit tests here.
11 @echo Starting tests...11 @echo Starting tests...
12 @$(PYTHON) /usr/bin/nosetests --nologcapture --with-coverage unit_tests12 @$(PYTHON) /usr/bin/nosetests -v --nologcapture --with-coverage unit_tests
1313
14functional_test:14functional_test:
15 @echo Starting Amulet tests...15 @echo Starting Amulet tests...
16 # https://bugs.launchpad.net/amulet/+bug/1320357
17 @juju test -v -p AMULET_HTTP_PROXY,AMULET_OS_VIP --timeout 270016 @juju test -v -p AMULET_HTTP_PROXY,AMULET_OS_VIP --timeout 2700
1817
19bin/charm_helpers_sync.py:18bin/charm_helpers_sync.py:
2019
=== modified file 'actions.yaml'
--- actions.yaml 2015-04-07 13:58:41 +0000
+++ actions.yaml 2015-10-14 14:39:53 +0000
@@ -1,2 +1,4 @@
1git-reinstall:1git-reinstall:
2 description: Reinstall openstack-dashboard from the openstack-origin-git repositories.2 description: Reinstall openstack-dashboard from the openstack-origin-git repositories.
3openstack-upgrade:
4 description: Perform openstack upgrades. Config option action-managed-upgrade must be set to True.
35
=== added symlink 'actions/openstack-upgrade'
=== target is u'openstack_upgrade.py'
=== added file 'actions/openstack_upgrade.py'
--- actions/openstack_upgrade.py 1970-01-01 00:00:00 +0000
+++ actions/openstack_upgrade.py 2015-10-14 14:39:53 +0000
@@ -0,0 +1,34 @@
1#!/usr/bin/python
2import sys
3
4sys.path.append('hooks/')
5
6from charmhelpers.contrib.openstack.utils import (
7 do_action_openstack_upgrade,
8)
9
10from horizon_utils import (
11 do_openstack_upgrade,
12)
13
14from horizon_hooks import (
15 config_changed,
16 CONFIGS,
17)
18
19
20def openstack_upgrade():
21 """Upgrade packages to config-set Openstack version.
22
23 If the charm was installed from source we cannot upgrade it.
24 For backwards compatibility a config flag must be set for this
25 code to run, otherwise a full service level upgrade will fire
26 on config-changed."""
27
28 if do_action_openstack_upgrade('openstack-dashboard',
29 do_openstack_upgrade,
30 CONFIGS):
31 config_changed()
32
33if __name__ == '__main__':
34 openstack_upgrade()
035
=== modified file 'config.yaml'
--- config.yaml 2015-07-10 14:18:48 +0000
+++ config.yaml 2015-10-14 14:39:53 +0000
@@ -153,6 +153,14 @@
153 In order for this charm to function correctly, the privacy extension153 In order for this charm to function correctly, the privacy extension
154 must be disabled and a non-temporary address must be154 must be disabled and a non-temporary address must be
155 configured/available on your network interface.155 configured/available on your network interface.
156 endpoint-type:
157 type: string
158 default:
159 description: |
160 Specifies the endpoint types to use for endpoints in the Keystone
161 service catalog. Valid values are 'publicURL', 'internalURL',
162 and 'adminURL'. Both the primary and secondary endpoint types can
163 be specified by providing multiple comma delimited values.
156 nagios_context:164 nagios_context:
157 default: "juju"165 default: "juju"
158 type: string166 type: string
@@ -163,7 +171,7 @@
163 .171 .
164 juju-postgresql-0172 juju-postgresql-0
165 .173 .
166 If you're running multiple environments with the same services in them174 If you are running multiple environments with the same services in them
167 this allows you to differentiate between them.175 this allows you to differentiate between them.
168 nagios_check_http_params:176 nagios_check_http_params:
169 default: "-H localhost -I 127.0.0.1 -u '/' -e 200,301,302"177 default: "-H localhost -I 127.0.0.1 -u '/' -e 200,301,302"
@@ -175,4 +183,25 @@
175 description: |183 description: |
176 A comma-separated list of nagios servicegroups. If left empty, the184 A comma-separated list of nagios servicegroups. If left empty, the
177 nagios_context will be used as the servicegroup.185 nagios_context will be used as the servicegroup.
178186 action-managed-upgrade:
187 type: boolean
188 default: False
189 description: |
190 If True enables openstack upgrades for this charm via juju actions.
191 You will still need to set openstack-origin to the new repository but
192 instead of an upgrade running automatically across all units, it will
193 wait for you to execute the openstack-upgrade action for this charm on
194 each unit. If False it will revert to existing behavior of upgrading
195 all units on config change.
196 apache_http_addendum:
197 type: string
198 default: ''
199 description: |
200 Extra stanzas to be inserted into the HTTP virtual host configuration.
201 May be used to specify rewrite rules, for example.
202 apache_https_addendum:
203 type: string
204 default: ''
205 description: |
206 Extra stanzas to be inserted into the HTTPS virtual host configuration.
207 May be used to specify rewrite rules, for example.
179208
=== modified file 'hooks/charmhelpers/contrib/openstack/utils.py'
--- hooks/charmhelpers/contrib/openstack/utils.py 2015-09-04 13:59:26 +0000
+++ hooks/charmhelpers/contrib/openstack/utils.py 2015-10-14 14:39:53 +0000
@@ -25,6 +25,7 @@
25import re25import re
2626
27import six27import six
28import traceback
28import yaml29import yaml
2930
30from charmhelpers.contrib.network import ip31from charmhelpers.contrib.network import ip
@@ -34,6 +35,8 @@
34)35)
3536
36from charmhelpers.core.hookenv import (37from charmhelpers.core.hookenv import (
38 action_fail,
39 action_set,
37 config,40 config,
38 log as juju_log,41 log as juju_log,
39 charm_dir,42 charm_dir,
@@ -114,6 +117,7 @@
114 ('2.2.1', 'kilo'),117 ('2.2.1', 'kilo'),
115 ('2.2.2', 'kilo'),118 ('2.2.2', 'kilo'),
116 ('2.3.0', 'liberty'),119 ('2.3.0', 'liberty'),
120 ('2.4.0', 'liberty'),
117])121])
118122
119# >= Liberty version->codename mapping123# >= Liberty version->codename mapping
@@ -748,3 +752,47 @@
748 return projects[key]752 return projects[key]
749753
750 return None754 return None
755
756
757def do_action_openstack_upgrade(package, upgrade_callback, configs):
758 """Perform action-managed OpenStack upgrade.
759
760 Upgrades packages to the configured openstack-origin version and sets
761 the corresponding action status as a result.
762
763 If the charm was installed from source we cannot upgrade it.
764 For backwards compatibility a config flag (action-managed-upgrade) must
765 be set for this code to run, otherwise a full service level upgrade will
766 fire on config-changed.
767
768 @param package: package name for determining if upgrade available
769 @param upgrade_callback: function callback to charm's upgrade function
770 @param configs: templating object derived from OSConfigRenderer class
771
772 @return: True if upgrade successful; False if upgrade failed or skipped
773 """
774 ret = False
775
776 if git_install_requested():
777 action_set({'outcome': 'installed from source, skipped upgrade.'})
778 else:
779 if openstack_upgrade_available(package):
780 if config('action-managed-upgrade'):
781 juju_log('Upgrading OpenStack release')
782
783 try:
784 upgrade_callback(configs=configs)
785 action_set({'outcome': 'success, upgrade completed.'})
786 ret = True
787 except:
788 action_set({'outcome': 'upgrade failed, see traceback.'})
789 action_set({'traceback': traceback.format_exc()})
790 action_fail('do_openstack_upgrade resulted in an '
791 'unexpected error')
792 else:
793 action_set({'outcome': 'action-managed-upgrade config is '
794 'False, skipped upgrade.'})
795 else:
796 action_set({'outcome': 'no upgrade available.'})
797
798 return ret
751799
=== added symlink 'hooks/dashboard-plugin-relation-changed'
=== target is u'horizon_hooks.py'
=== added symlink 'hooks/dashboard-plugin-relation-joined'
=== target is u'horizon_hooks.py'
=== removed symlink 'hooks/dashboard-plugin-relation-joined'
=== target was u'horizon_hooks.py'
=== modified file 'hooks/horizon_contexts.py'
--- hooks/horizon_contexts.py 2015-04-09 14:56:00 +0000
+++ hooks/horizon_contexts.py 2015-10-14 14:39:53 +0000
@@ -6,7 +6,8 @@
6 relation_get,6 relation_get,
7 local_unit,7 local_unit,
8 unit_get,8 unit_get,
9 log9 log,
10 ERROR,
10)11)
11from charmhelpers.contrib.openstack.context import (12from charmhelpers.contrib.openstack.context import (
12 OSContextGenerator,13 OSContextGenerator,
@@ -28,6 +29,12 @@
28from base64 import b64decode29from base64 import b64decode
29import os30import os
3031
32VALID_ENDPOINT_TYPES = {
33 'PUBLICURL': 'publicURL',
34 'INTERNALURL': 'internalURL',
35 'ADMINURL': 'adminURL',
36}
37
3138
32class HorizonHAProxyContext(HAProxyContext):39class HorizonHAProxyContext(HAProxyContext):
33 def __call__(self):40 def __call__(self):
@@ -69,6 +76,22 @@
69class IdentityServiceContext(OSContextGenerator):76class IdentityServiceContext(OSContextGenerator):
70 interfaces = ['identity-service']77 interfaces = ['identity-service']
7178
79 def normalize(self, endpoint_type):
80 """Normalizes the endpoint type values.
81
82 :param endpoint_type (string): the endpoint type to normalize.
83 :raises: Exception if the endpoint type is not valid.
84 :return (string): the normalized form of the endpoint type.
85 """
86 normalized_form = VALID_ENDPOINT_TYPES.get(endpoint_type.upper(), None)
87 if not normalized_form:
88 msg = ('Endpoint type specified %s is not a valid'
89 ' endpoint type' % endpoint_type)
90 log(msg, ERROR)
91 raise Exception(msg)
92
93 return normalized_form
94
72 def __call__(self):95 def __call__(self):
73 log('Generating template context for identity-service')96 log('Generating template context for identity-service')
74 ctxt = {}97 ctxt = {}
@@ -106,6 +129,21 @@
106 avail_regions = map(lambda r: {'endpoint': r[0], 'title': r[1]},129 avail_regions = map(lambda r: {'endpoint': r[0], 'title': r[1]},
107 regions)130 regions)
108 ctxt['regions'] = sorted(avail_regions)131 ctxt['regions'] = sorted(avail_regions)
132
133 # Allow the endpoint types to be specified via a config parameter.
134 # The config parameter accepts either:
135 # 1. a single endpoint type to be specified, in which case the
136 # primary endpoint is configured
137 # 2. a list of endpoint types, in which case the primary endpoint
138 # is taken as the first entry and the secondary endpoint is
139 # taken as the second entry. All subsequent entries are ignored.
140 ep_types = config('endpoint-type')
141 if ep_types:
142 ep_types = [self.normalize(e) for e in ep_types.split(',')]
143 ctxt['primary_endpoint'] = ep_types[0]
144 if len(ep_types) > 1:
145 ctxt['secondary_endpoint'] = ep_types[1]
146
109 return ctxt147 return ctxt
110148
111149
@@ -134,7 +172,8 @@
134 ''' Grab cert and key from configuraton for SSL config '''172 ''' Grab cert and key from configuraton for SSL config '''
135 ctxt = {173 ctxt = {
136 'http_port': 70,174 'http_port': 70,
137 'https_port': 433175 'https_port': 433,
176 'apache_http_addendum': config("apache_http_addendum"),
138 }177 }
139 return ctxt178 return ctxt
140179
@@ -162,6 +201,8 @@
162 ctxt = {201 ctxt = {
163 'ssl_configured': False,202 'ssl_configured': False,
164 }203 }
204 ctxt['apache_https_addendum'] = config("apache_https_addendum")
205
165 return ctxt206 return ctxt
166207
167208
@@ -172,3 +213,28 @@
172 'disable_router': False if config('profile') in ['cisco'] else True213 'disable_router': False if config('profile') in ['cisco'] else True
173 }214 }
174 return ctxt215 return ctxt
216
217
218class LocalSettingsContext(OSContextGenerator):
219 def __call__(self):
220 ''' Additional config stanzas to be appended to local_settings.py '''
221
222 relations = []
223
224 for rid in relation_ids("plugin"):
225 try:
226 unit = related_units(rid)[0]
227 except IndexError:
228 pass
229 else:
230 rdata = relation_get(unit=unit, rid=rid)
231 if set(('local-settings', 'priority')) <= set(rdata.keys()):
232 relations.append((unit, rdata))
233
234 ctxt = {
235 'settings': [
236 '# {0}\n{1}'.format(u, rd['local-settings'])
237 for u, rd in sorted(relations,
238 key=lambda r: r[1]['priority'])]
239 }
240 return ctxt
175241
=== modified file 'hooks/horizon_hooks.py'
--- hooks/horizon_hooks.py 2015-09-03 19:18:51 +0000
+++ hooks/horizon_hooks.py 2015-10-14 14:39:53 +0000
@@ -58,7 +58,7 @@
58CONFIGS = register_configs()58CONFIGS = register_configs()
5959
6060
61@hooks.hook('install')61@hooks.hook('install.real')
62def install():62def install():
63 execd_preinstall()63 execd_preinstall()
64 configure_installation_source(config('openstack-origin'))64 configure_installation_source(config('openstack-origin'))
@@ -106,7 +106,7 @@
106 if git_install_requested():106 if git_install_requested():
107 if config_value_changed('openstack-origin-git'):107 if config_value_changed('openstack-origin-git'):
108 git_install(config('openstack-origin-git'))108 git_install(config('openstack-origin-git'))
109 else:109 elif not config('action-managed-upgrade'):
110 if openstack_upgrade_available('openstack-dashboard'):110 if openstack_upgrade_available('openstack-dashboard'):
111 do_openstack_upgrade(configs=CONFIGS)111 do_openstack_upgrade(configs=CONFIGS)
112112
@@ -247,16 +247,23 @@
247247
248248
249@hooks.hook('dashboard-plugin-relation-joined')249@hooks.hook('dashboard-plugin-relation-joined')
250def update_dashboard_plugin(rel_id=None):250def plugin_relation_joined(rel_id=None):
251 if git_install_requested():251 if git_install_requested():
252 bin_path = git_pip_venv_dir(config('openstack-origin-git'))252 bin_path = git_pip_venv_dir(config('openstack-origin-git'))
253 else:253 else:
254 bin_path = '/usr/bin'254 bin_path = '/usr/bin'
255 relation_set(relation_id=rel_id,255 relation_set(release=os_release("openstack-dashboard"),
256 relation_id=rel_id,
256 bin_path=bin_path,257 bin_path=bin_path,
257 openstack_dir=INSTALL_DIR)258 openstack_dir=INSTALL_DIR)
258259
259260
261@hooks.hook('dashboard-plugin-relation-changed')
262@restart_on_change(restart_map())
263def update_plugin_config():
264 CONFIGS.write(LOCAL_SETTINGS)
265
266
260def main():267def main():
261 try:268 try:
262 hooks.execute(sys.argv)269 hooks.execute(sys.argv)
263270
=== modified file 'hooks/horizon_utils.py'
--- hooks/horizon_utils.py 2015-09-03 19:18:51 +0000
+++ hooks/horizon_utils.py 2015-10-14 14:39:53 +0000
@@ -101,7 +101,8 @@
101 (LOCAL_SETTINGS, {101 (LOCAL_SETTINGS, {
102 'hook_contexts': [horizon_contexts.HorizonContext(),102 'hook_contexts': [horizon_contexts.HorizonContext(),
103 horizon_contexts.IdentityServiceContext(),103 horizon_contexts.IdentityServiceContext(),
104 context.SyslogContext()],104 context.SyslogContext(),
105 horizon_contexts.LocalSettingsContext()],
105 'services': ['apache2']106 'services': ['apache2']
106 }),107 }),
107 (APACHE_CONF, {108 (APACHE_CONF, {
@@ -262,12 +263,12 @@
262 raise Exception("IPv6 is not supported in the charms for Ubuntu "263 raise Exception("IPv6 is not supported in the charms for Ubuntu "
263 "versions less than Trusty 14.04")264 "versions less than Trusty 14.04")
264265
265 # NOTE(xianghui): Need to install haproxy(1.5.3) from trusty-backports266 # Need haproxy >= 1.5.3 for ipv6 so for Trusty if we are <= Kilo we need to
266 # to support ipv6 address, so check is required to make sure not267 # use trusty-backports otherwise we can use the UCA.
267 # breaking other versions, IPv6 only support for >= Trusty268 os_pkg = 'openstack-dashboard'
268 if ubuntu_rel == 'trusty':269 if ubuntu_rel == 'trusty' and os_release(os_pkg) < 'liberty':
269 add_source('deb http://archive.ubuntu.com/ubuntu trusty-backports'270 add_source('deb http://archive.ubuntu.com/ubuntu trusty-backports '
270 ' main')271 'main')
271 apt_update()272 apt_update()
272 apt_install('haproxy/trusty-backports', fatal=True)273 apt_install('haproxy/trusty-backports', fatal=True)
273274
274275
=== modified symlink 'hooks/install' (properties changed: -x to +x)
=== target was u'horizon_hooks.py'
--- hooks/install 1970-01-01 00:00:00 +0000
+++ hooks/install 2015-10-14 14:39:53 +0000
@@ -0,0 +1,20 @@
1#!/bin/bash
2# Wrapper to deal with newer Ubuntu versions that don't have py2 installed
3# by default.
4
5declare -a DEPS=('apt' 'netaddr' 'netifaces' 'pip' 'yaml')
6
7check_and_install() {
8 pkg="${1}-${2}"
9 if ! dpkg -s ${pkg} 2>&1 > /dev/null; then
10 apt-get -y install ${pkg}
11 fi
12}
13
14PYTHON="python"
15
16for dep in ${DEPS[@]}; do
17 check_and_install ${PYTHON} ${dep}
18done
19
20exec ./hooks/install.real
021
=== added symlink 'hooks/install.real'
=== target is u'horizon_hooks.py'
=== modified file 'metadata.yaml'
--- metadata.yaml 2015-09-10 20:38:16 +0000
+++ metadata.yaml 2015-10-14 14:39:53 +0000
@@ -15,6 +15,7 @@
15 interface: http15 interface: http
16 dashboard-plugin:16 dashboard-plugin:
17 interface: dashboard-plugin17 interface: dashboard-plugin
18 scope: container
18requires:19requires:
19 identity-service:20 identity-service:
20 interface: keystone21 interface: keystone
2122
=== modified file 'templates/default'
--- templates/default 2013-07-15 16:25:46 +0000
+++ templates/default 2015-10-14 14:39:53 +0000
@@ -29,4 +29,6 @@
2929
30 CustomLog ${APACHE_LOG_DIR}/access.log combined30 CustomLog ${APACHE_LOG_DIR}/access.log combined
3131
32{{ apache_http_addendum }}
33
32</VirtualHost>34</VirtualHost>
3335
=== modified file 'templates/default-ssl'
--- templates/default-ssl 2013-07-15 16:25:46 +0000
+++ templates/default-ssl 2015-10-14 14:39:53 +0000
@@ -46,5 +46,7 @@
46 downgrade-1.0 force-response-1.046 downgrade-1.0 force-response-1.0
47 BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown47 BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
4848
49{{ apache_https_addendum }}
50
49 </VirtualHost>51 </VirtualHost>
50</IfModule>52</IfModule>
5153
=== modified file 'templates/essex/local_settings.py'
--- templates/essex/local_settings.py 2014-02-27 10:07:57 +0000
+++ templates/essex/local_settings.py 2015-10-14 14:39:53 +0000
@@ -118,3 +118,5 @@
118 }118 }
119 }119 }
120}120}
121
122{{ settings|join('\n\n') }}
121123
=== modified file 'templates/folsom/local_settings.py'
--- templates/folsom/local_settings.py 2014-05-28 16:05:37 +0000
+++ templates/folsom/local_settings.py 2015-10-14 14:39:53 +0000
@@ -167,3 +167,5 @@
167# offline compression by default. To enable online compression, install167# offline compression by default. To enable online compression, install
168# the node-less package and enable the following option.168# the node-less package and enable the following option.
169COMPRESS_OFFLINE = {{ compress_offline }}169COMPRESS_OFFLINE = {{ compress_offline }}
170
171{{ settings|join('\n\n') }}
170\ No newline at end of file172\ No newline at end of file
171173
=== modified file 'templates/grizzly/local_settings.py'
--- templates/grizzly/local_settings.py 2014-05-28 16:05:37 +0000
+++ templates/grizzly/local_settings.py 2015-10-14 14:39:53 +0000
@@ -263,3 +263,5 @@
263 }263 }
264 }264 }
265}265}
266
267{{ settings|join('\n\n') }}
266268
=== modified file 'templates/havana/local_settings.py'
--- templates/havana/local_settings.py 2014-07-22 07:18:55 +0000
+++ templates/havana/local_settings.py 2015-10-14 14:39:53 +0000
@@ -483,3 +483,5 @@
483# installations should have this set accordingly. For more information483# installations should have this set accordingly. For more information
484# see https://docs.djangoproject.com/en/dev/ref/settings/.484# see https://docs.djangoproject.com/en/dev/ref/settings/.
485ALLOWED_HOSTS = '*'485ALLOWED_HOSTS = '*'
486
487{{ settings|join('\n\n') }}
486\ No newline at end of file488\ No newline at end of file
487489
=== modified file 'templates/icehouse/local_settings.py'
--- templates/icehouse/local_settings.py 2014-12-01 23:45:41 +0000
+++ templates/icehouse/local_settings.py 2015-10-14 14:39:53 +0000
@@ -212,6 +212,9 @@
212# in the Keystone service catalog. Use this setting when Horizon is running212# in the Keystone service catalog. Use this setting when Horizon is running
213# external to the OpenStack environment. The default is 'publicURL'.213# external to the OpenStack environment. The default is 'publicURL'.
214#OPENSTACK_ENDPOINT_TYPE = "publicURL"214#OPENSTACK_ENDPOINT_TYPE = "publicURL"
215{% if primary_endpoint -%}
216OPENSTACK_ENDPOINT_TYPE = {{ primary_endpoint }}
217{% endif -%}
215218
216# SECONDARY_ENDPOINT_TYPE specifies the fallback endpoint type to use in the219# SECONDARY_ENDPOINT_TYPE specifies the fallback endpoint type to use in the
217# case that OPENSTACK_ENDPOINT_TYPE is not present in the endpoints220# case that OPENSTACK_ENDPOINT_TYPE is not present in the endpoints
@@ -219,6 +222,9 @@
219# external to the OpenStack environment. The default is None. This222# external to the OpenStack environment. The default is None. This
220# value should differ from OPENSTACK_ENDPOINT_TYPE if used.223# value should differ from OPENSTACK_ENDPOINT_TYPE if used.
221#SECONDARY_ENDPOINT_TYPE = "publicURL"224#SECONDARY_ENDPOINT_TYPE = "publicURL"
225{% if secondary_endpoint -%}
226SECONDARY_ENDPOINT_TYPE = {{ secondary_endpoint }}
227{% endif -%}
222228
223# The number of objects (Swift containers/objects or images) to display229# The number of objects (Swift containers/objects or images) to display
224# on a single page before providing a paging element (a "more" link)230# on a single page before providing a paging element (a "more" link)
@@ -514,3 +520,5 @@
514# installations should have this set accordingly. For more information520# installations should have this set accordingly. For more information
515# see https://docs.djangoproject.com/en/dev/ref/settings/.521# see https://docs.djangoproject.com/en/dev/ref/settings/.
516ALLOWED_HOSTS = '*'522ALLOWED_HOSTS = '*'
523
524{{ settings|join('\n\n') }}
517\ No newline at end of file525\ No newline at end of file
518526
=== modified file 'templates/juno/local_settings.py'
--- templates/juno/local_settings.py 2014-12-01 23:45:41 +0000
+++ templates/juno/local_settings.py 2015-10-14 14:39:53 +0000
@@ -250,6 +250,9 @@
250# in the Keystone service catalog. Use this setting when Horizon is running250# in the Keystone service catalog. Use this setting when Horizon is running
251# external to the OpenStack environment. The default is 'publicURL'.251# external to the OpenStack environment. The default is 'publicURL'.
252#OPENSTACK_ENDPOINT_TYPE = "publicURL"252#OPENSTACK_ENDPOINT_TYPE = "publicURL"
253{% if primary_endpoint -%}
254OPENSTACK_ENDPOINT_TYPE = {{ primary_endpoint }}
255{% endif -%}
253256
254# SECONDARY_ENDPOINT_TYPE specifies the fallback endpoint type to use in the257# SECONDARY_ENDPOINT_TYPE specifies the fallback endpoint type to use in the
255# case that OPENSTACK_ENDPOINT_TYPE is not present in the endpoints258# case that OPENSTACK_ENDPOINT_TYPE is not present in the endpoints
@@ -257,6 +260,9 @@
257# external to the OpenStack environment. The default is None. This260# external to the OpenStack environment. The default is None. This
258# value should differ from OPENSTACK_ENDPOINT_TYPE if used.261# value should differ from OPENSTACK_ENDPOINT_TYPE if used.
259#SECONDARY_ENDPOINT_TYPE = "publicURL"262#SECONDARY_ENDPOINT_TYPE = "publicURL"
263{% if secondary_endpoint -%}
264SECONDARY_ENDPOINT_TYPE = {{ secondary_endpoint }}
265{% endif -%}
260266
261# The number of objects (Swift containers/objects or images) to display267# The number of objects (Swift containers/objects or images) to display
262# on a single page before providing a paging element (a "more" link)268# on a single page before providing a paging element (a "more" link)
@@ -619,3 +625,5 @@
619# installations should have this set accordingly. For more information625# installations should have this set accordingly. For more information
620# see https://docs.djangoproject.com/en/dev/ref/settings/.626# see https://docs.djangoproject.com/en/dev/ref/settings/.
621ALLOWED_HOSTS = '*'627ALLOWED_HOSTS = '*'
628
629{{ settings|join('\n\n') }}
622\ No newline at end of file630\ No newline at end of file
623631
=== modified file 'tests/00-setup'
--- tests/00-setup 2015-08-21 18:42:43 +0000
+++ tests/00-setup 2015-10-14 14:39:53 +0000
@@ -5,6 +5,7 @@
5sudo add-apt-repository --yes ppa:juju/stable5sudo add-apt-repository --yes ppa:juju/stable
6sudo apt-get update --yes6sudo apt-get update --yes
7sudo apt-get install --yes amulet \7sudo apt-get install --yes amulet \
8 distro-info-data \
8 python-cinderclient \9 python-cinderclient \
9 python-distro-info \10 python-distro-info \
10 python-glanceclient \11 python-glanceclient \
1112
=== modified file 'tests/tests.yaml'
--- tests/tests.yaml 2015-08-21 18:42:43 +0000
+++ tests/tests.yaml 2015-10-14 14:39:53 +0000
@@ -8,7 +8,7 @@
8 - ppa:juju/stable8 - ppa:juju/stable
9packages:9packages:
10 - amulet10 - amulet
11 - python-amulet11 - distro-info-data
12 - python-cinderclient12 - python-cinderclient
13 - python-distro-info13 - python-distro-info
14 - python-glanceclient14 - python-glanceclient
1515
=== added file 'unit_tests/test_actions_openstack_upgrade.py'
--- unit_tests/test_actions_openstack_upgrade.py 1970-01-01 00:00:00 +0000
+++ unit_tests/test_actions_openstack_upgrade.py 2015-10-14 14:39:53 +0000
@@ -0,0 +1,53 @@
1from mock import patch
2import os
3
4os.environ['JUJU_UNIT_NAME'] = 'openstack-dashboard'
5
6with patch('horizon_utils.register_configs') as register_configs:
7 import openstack_upgrade
8
9from test_utils import (
10 CharmTestCase
11)
12
13TO_PATCH = [
14 'do_openstack_upgrade',
15 'config_changed',
16]
17
18
19class TestHorizonUpgradeActions(CharmTestCase):
20
21 def setUp(self):
22 super(TestHorizonUpgradeActions, self).setUp(openstack_upgrade,
23 TO_PATCH)
24
25 @patch('charmhelpers.contrib.openstack.utils.config')
26 @patch('charmhelpers.contrib.openstack.utils.action_set')
27 @patch('charmhelpers.contrib.openstack.utils.git_install_requested')
28 @patch('charmhelpers.contrib.openstack.utils.openstack_upgrade_available')
29 def test_openstack_upgrade_true(self, upgrade_avail, git_requested,
30 action_set, config):
31 git_requested.return_value = False
32 upgrade_avail.return_value = True
33 config.return_value = True
34
35 openstack_upgrade.openstack_upgrade()
36
37 self.assertTrue(self.do_openstack_upgrade.called)
38 self.assertTrue(self.config_changed.called)
39
40 @patch('charmhelpers.contrib.openstack.utils.config')
41 @patch('charmhelpers.contrib.openstack.utils.action_set')
42 @patch('charmhelpers.contrib.openstack.utils.git_install_requested')
43 @patch('charmhelpers.contrib.openstack.utils.openstack_upgrade_available')
44 def test_openstack_upgrade_false(self, upgrade_avail, git_requested,
45 action_set, config):
46 git_requested.return_value = False
47 upgrade_avail.return_value = True
48 config.return_value = False
49
50 openstack_upgrade.openstack_upgrade()
51
52 self.assertFalse(self.do_openstack_upgrade.called)
53 self.assertFalse(self.config_changed.called)
054
=== modified file 'unit_tests/test_horizon_contexts.py'
--- unit_tests/test_horizon_contexts.py 2015-04-09 14:34:44 +0000
+++ unit_tests/test_horizon_contexts.py 2015-10-14 14:39:53 +0000
@@ -47,19 +47,23 @@
47 self.pwgen.return_value = "secret"47 self.pwgen.return_value = "secret"
4848
49 def test_Apachecontext(self):49 def test_Apachecontext(self):
50 self.test_config.set('apache_http_addendum', 'RewriteEngine on')
50 self.assertEquals(horizon_contexts.ApacheContext()(),51 self.assertEquals(horizon_contexts.ApacheContext()(),
51 {'http_port': 70, 'https_port': 433})52 {'http_port': 70, 'https_port': 433,
53 'apache_http_addendum': 'RewriteEngine on'})
5254
53 @patch.object(horizon_contexts, 'get_ca_cert', lambda: None)55 @patch.object(horizon_contexts, 'get_ca_cert', lambda: None)
54 @patch('os.chmod')56 @patch('os.chmod')
55 def test_ApacheSSLContext_enabled(self, _chmod):57 def test_ApacheSSLContext_enabled(self, _chmod):
56 self.get_cert.return_value = ('cert', 'key')58 self.get_cert.return_value = ('cert', 'key')
57 self.b64decode.side_effect = ['cert', 'key']59 self.b64decode.side_effect = ['cert', 'key']
60 self.test_config.set('apache_https_addendum', 'RewriteEngine off')
58 with patch_open() as (_open, _file):61 with patch_open() as (_open, _file):
59 self.assertEquals(horizon_contexts.ApacheSSLContext()(),62 self.assertEquals(horizon_contexts.ApacheSSLContext()(),
60 {'ssl_configured': True,63 {'ssl_configured': True,
61 'ssl_cert': '/etc/ssl/certs/dashboard.cert',64 'ssl_cert': '/etc/ssl/certs/dashboard.cert',
62 'ssl_key': '/etc/ssl/private/dashboard.key'})65 'ssl_key': '/etc/ssl/private/dashboard.key',
66 'apache_https_addendum': 'RewriteEngine off'})
63 _open.assert_has_calls([67 _open.assert_has_calls([
64 call('/etc/ssl/certs/dashboard.cert', 'w'),68 call('/etc/ssl/certs/dashboard.cert', 'w'),
65 call('/etc/ssl/private/dashboard.key', 'w')69 call('/etc/ssl/private/dashboard.key', 'w')
@@ -75,7 +79,8 @@
75 def test_ApacheSSLContext_disabled(self):79 def test_ApacheSSLContext_disabled(self):
76 self.get_cert.return_value = (None, None)80 self.get_cert.return_value = (None, None)
77 self.assertEquals(horizon_contexts.ApacheSSLContext()(),81 self.assertEquals(horizon_contexts.ApacheSSLContext()(),
78 {'ssl_configured': False})82 {'ssl_configured': False,
83 'apache_https_addendum': ''})
7984
80 def test_HorizonContext_defaults(self):85 def test_HorizonContext_defaults(self):
81 self.assertEquals(horizon_contexts.HorizonContext()(),86 self.assertEquals(horizon_contexts.HorizonContext()(),
@@ -212,6 +217,22 @@
212 {'endpoint': 'http://foo:5000/v2.0',217 {'endpoint': 'http://foo:5000/v2.0',
213 'title': 'regionTwo'}]})218 'title': 'regionTwo'}]})
214219
220 def test_IdentityServiceContext_endpoint_type(self):
221 self.test_config.set('endpoint-type', 'internalURL')
222 self.assertEqual(horizon_contexts.IdentityServiceContext()(),
223 {'primary_endpoint': 'internalURL'})
224
225 def test_IdentityServiceContext_multi_endpoint_types(self):
226 self.test_config.set('endpoint-type', 'internalURL,publicURL')
227 self.assertEqual(horizon_contexts.IdentityServiceContext()(),
228 {'primary_endpoint': 'internalURL',
229 'secondary_endpoint': 'publicURL'})
230
231 def test_IdentityServiceContext_invalid_endpoint_type(self):
232 self.test_config.set('endpoint-type', 'this_is_bad')
233 with self.assertRaises(Exception):
234 horizon_contexts.IdentityServiceContext()()
235
215 def test_HorizonHAProxyContext_no_cluster(self):236 def test_HorizonHAProxyContext_no_cluster(self):
216 self.relation_ids.return_value = []237 self.relation_ids.return_value = []
217 self.local_unit.return_value = 'openstack-dashboard/0'238 self.local_unit.return_value = 'openstack-dashboard/0'
@@ -251,3 +272,18 @@
251 self.test_config.set('profile', None)272 self.test_config.set('profile', None)
252 self.assertEquals(horizon_contexts.RouterSettingContext()(),273 self.assertEquals(horizon_contexts.RouterSettingContext()(),
253 {'disable_router': True, })274 {'disable_router': True, })
275
276 def test_LocalSettingsContext(self):
277 self.relation_ids.return_value = ['plugin:0', 'plugin-too:0']
278 self.related_units.side_effect = [['horizon-plugin/0'],
279 ['horizon-plugin-too/0']]
280 self.relation_get.side_effect = [{'priority': 99,
281 'local-settings': 'FOO = True'},
282 {'priority': 60,
283 'local-settings': 'BAR = False'}]
284
285 self.assertEquals(horizon_contexts.LocalSettingsContext()(),
286 {'settings': ['# horizon-plugin-too/0\n'
287 'BAR = False',
288 '# horizon-plugin/0\n'
289 'FOO = True']})
254290
=== modified file 'unit_tests/test_horizon_hooks.py'
--- unit_tests/test_horizon_hooks.py 2015-09-04 15:16:58 +0000
+++ unit_tests/test_horizon_hooks.py 2015-10-14 14:39:53 +0000
@@ -308,25 +308,32 @@
308 self._call_hook('website-relation-joined')308 self._call_hook('website-relation-joined')
309 self.relation_set.assert_called_with(port=70, hostname='192.168.1.1')309 self.relation_set.assert_called_with(port=70, hostname='192.168.1.1')
310310
311 @patch.object(hooks, 'os_release')
311 @patch.object(hooks, 'git_install_requested')312 @patch.object(hooks, 'git_install_requested')
312 def test_dashboard_config_joined_not_git(self, _git_requested):313 def test_dashboard_config_joined_not_git(
314 self, _git_requested, _os_release):
313 _git_requested.return_value = False315 _git_requested.return_value = False
316 _os_release.return_value = 'vivid'
314 self._call_hook('dashboard-plugin-relation-joined')317 self._call_hook('dashboard-plugin-relation-joined')
315 self.relation_set.assert_called_with(318 self.relation_set.assert_called_with(
319 release='vivid',
316 bin_path='/usr/bin',320 bin_path='/usr/bin',
317 openstack_dir='/usr/share/openstack-dashboard',321 openstack_dir='/usr/share/openstack-dashboard',
318 relation_id=None322 relation_id=None
319 )323 )
320324
325 @patch.object(hooks, 'os_release')
321 @patch.object(hooks, 'git_pip_venv_dir')326 @patch.object(hooks, 'git_pip_venv_dir')
322 @patch.object(hooks, 'git_install_requested')327 @patch.object(hooks, 'git_install_requested')
323 def test_dashboard_config_joined_git(self, _git_requested,328 def test_dashboard_config_joined_git(
324 _git_pip_venv_dir):329 self, _git_requested, _git_pip_venv_dir, _os_release):
325 expected_bin_path = '/mnt/fuji/venv'330 expected_bin_path = '/mnt/fuji/venv'
326 _git_requested.return_value = True331 _git_requested.return_value = True
327 _git_pip_venv_dir.return_value = expected_bin_path332 _git_pip_venv_dir.return_value = expected_bin_path
333 _os_release.return_value = 'wily'
328 self._call_hook('dashboard-plugin-relation-joined')334 self._call_hook('dashboard-plugin-relation-joined')
329 self.relation_set.assert_called_with(335 self.relation_set.assert_called_with(
336 release='wily',
330 bin_path=expected_bin_path,337 bin_path=expected_bin_path,
331 openstack_dir='/usr/share/openstack-dashboard',338 openstack_dir='/usr/share/openstack-dashboard',
332 relation_id=None339 relation_id=None

Subscribers

People subscribed via source and target branches

to all changes: