Merge lp:~billy-olsen/charms/trusty/neutron-api/public-endpoint-host into lp:~openstack-charmers-archive/charms/trusty/neutron-api/next

Proposed by Billy Olsen
Status: Merged
Merged at revision: 118
Proposed branch: lp:~billy-olsen/charms/trusty/neutron-api/public-endpoint-host
Merge into: lp:~openstack-charmers-archive/charms/trusty/neutron-api/next
Diff against target: 259 lines (+98/-51)
3 files modified
config.yaml (+12/-0)
hooks/charmhelpers/contrib/openstack/ip.py (+49/-44)
unit_tests/test_neutron_api_hooks.py (+37/-7)
To merge this branch: bzr merge lp:~billy-olsen/charms/trusty/neutron-api/public-endpoint-host
Reviewer Review Type Date Requested Status
Corey Bryant (community) Approve
Review via email: mp+261007@code.launchpad.net

Description of the change

Provides a config option which allows the user to specify the public hostname used to advertise to keystone when creating endpoints.

To post a comment you must log in.
Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_lint_check #5045 neutron-api-next for billy-olsen mp261007
    LINT OK: passed

Build: http://10.245.162.77:8080/job/charm_lint_check/5045/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_unit_test #4725 neutron-api-next for billy-olsen mp261007
    UNIT OK: passed

Build: http://10.245.162.77:8080/job/charm_unit_test/4725/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_amulet_test #4451 neutron-api-next for billy-olsen mp261007
    AMULET OK: passed

Build: http://10.245.162.77:8080/job/charm_amulet_test/4451/

117. By Billy Olsen

merge with /next

118. By Billy Olsen

c-h sync

119. By Billy Olsen

Fix unit test error from c-h sync

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_lint_check #5069 neutron-api-next for billy-olsen mp261007
    LINT OK: passed

Build: http://10.245.162.77:8080/job/charm_lint_check/5069/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_unit_test #4748 neutron-api-next for billy-olsen mp261007
    UNIT OK: passed

Build: http://10.245.162.77:8080/job/charm_unit_test/4748/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_amulet_test #4476 neutron-api-next for billy-olsen mp261007
    AMULET OK: passed

Build: http://10.245.162.77:8080/job/charm_amulet_test/4476/

Revision history for this message
Corey Bryant (corey.bryant) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'config.yaml'
--- config.yaml 2015-05-21 15:02:07 +0000
+++ config.yaml 2015-06-04 23:28:32 +0000
@@ -235,6 +235,18 @@
235 192.168.0.0/24)235 192.168.0.0/24)
236 .236 .
237 This network will be used for public endpoints.237 This network will be used for public endpoints.
238 os-public-hostname:
239 type: string
240 default:
241 description: |
242 The hostname or address of the public endpoints created for neutron-api
243 in the keystone identity provider.
244 .
245 This value will be used for public endpoints. For example, an
246 os-public-hostname set to 'neutron-api.example.com' with ssl enabled
247 will create the following endpoint for neutron-api:
248 .
249 https://neutron-api.example.com:9696/
238 ssl_cert:250 ssl_cert:
239 type: string251 type: string
240 default:252 default:
241253
=== modified file 'hooks/charmhelpers/contrib/openstack/ip.py'
--- hooks/charmhelpers/contrib/openstack/ip.py 2015-03-16 14:16:02 +0000
+++ hooks/charmhelpers/contrib/openstack/ip.py 2015-06-04 23:28:32 +0000
@@ -17,6 +17,7 @@
17from charmhelpers.core.hookenv import (17from charmhelpers.core.hookenv import (
18 config,18 config,
19 unit_get,19 unit_get,
20 service_name,
20)21)
21from charmhelpers.contrib.network.ip import (22from charmhelpers.contrib.network.ip import (
22 get_address_in_network,23 get_address_in_network,
@@ -26,8 +27,6 @@
26)27)
27from charmhelpers.contrib.hahelpers.cluster import is_clustered28from charmhelpers.contrib.hahelpers.cluster import is_clustered
2829
29from functools import partial
30
31PUBLIC = 'public'30PUBLIC = 'public'
32INTERNAL = 'int'31INTERNAL = 'int'
33ADMIN = 'admin'32ADMIN = 'admin'
@@ -35,15 +34,18 @@
35ADDRESS_MAP = {34ADDRESS_MAP = {
36 PUBLIC: {35 PUBLIC: {
37 'config': 'os-public-network',36 'config': 'os-public-network',
38 'fallback': 'public-address'37 'fallback': 'public-address',
38 'override': 'os-public-hostname',
39 },39 },
40 INTERNAL: {40 INTERNAL: {
41 'config': 'os-internal-network',41 'config': 'os-internal-network',
42 'fallback': 'private-address'42 'fallback': 'private-address',
43 'override': 'os-internal-hostname',
43 },44 },
44 ADMIN: {45 ADMIN: {
45 'config': 'os-admin-network',46 'config': 'os-admin-network',
46 'fallback': 'private-address'47 'fallback': 'private-address',
48 'override': 'os-admin-hostname',
47 }49 }
48}50}
4951
@@ -57,15 +59,50 @@
57 :param endpoint_type: str endpoint type to resolve.59 :param endpoint_type: str endpoint type to resolve.
58 :param returns: str base URL for services on the current service unit.60 :param returns: str base URL for services on the current service unit.
59 """61 """
60 scheme = 'http'62 scheme = _get_scheme(configs)
61 if 'https' in configs.complete_contexts():63
62 scheme = 'https'
63 address = resolve_address(endpoint_type)64 address = resolve_address(endpoint_type)
64 if is_ipv6(address):65 if is_ipv6(address):
65 address = "[{}]".format(address)66 address = "[{}]".format(address)
67
66 return '%s://%s' % (scheme, address)68 return '%s://%s' % (scheme, address)
6769
6870
71def _get_scheme(configs):
72 """Returns the scheme to use for the url (either http or https)
73 depending upon whether https is in the configs value.
74
75 :param configs: OSTemplateRenderer config templating object to inspect
76 for a complete https context.
77 :returns: either 'http' or 'https' depending on whether https is
78 configured within the configs context.
79 """
80 scheme = 'http'
81 if configs and 'https' in configs.complete_contexts():
82 scheme = 'https'
83 return scheme
84
85
86def _get_address_override(endpoint_type=PUBLIC):
87 """Returns any address overrides that the user has defined based on the
88 endpoint type.
89
90 Note: this function allows for the service name to be inserted into the
91 address if the user specifies {service_name}.somehost.org.
92
93 :param endpoint_type: the type of endpoint to retrieve the override
94 value for.
95 :returns: any endpoint address or hostname that the user has overridden
96 or None if an override is not present.
97 """
98 override_key = ADDRESS_MAP[endpoint_type]['override']
99 addr_override = config(override_key)
100 if not addr_override:
101 return None
102 else:
103 return addr_override.format(service_name=service_name())
104
105
69def resolve_address(endpoint_type=PUBLIC):106def resolve_address(endpoint_type=PUBLIC):
70 """Return unit address depending on net config.107 """Return unit address depending on net config.
71108
@@ -77,7 +114,10 @@
77114
78 :param endpoint_type: Network endpoing type115 :param endpoint_type: Network endpoing type
79 """116 """
80 resolved_address = None117 resolved_address = _get_address_override(endpoint_type)
118 if resolved_address:
119 return resolved_address
120
81 vips = config('vip')121 vips = config('vip')
82 if vips:122 if vips:
83 vips = vips.split()123 vips = vips.split()
@@ -109,38 +149,3 @@
109 "clustered=%s)" % (net_type, clustered))149 "clustered=%s)" % (net_type, clustered))
110150
111 return resolved_address151 return resolved_address
112
113
114def endpoint_url(configs, url_template, port, endpoint_type=PUBLIC,
115 override=None):
116 """Returns the correct endpoint URL to advertise to Keystone.
117
118 This method provides the correct endpoint URL which should be advertised to
119 the keystone charm for endpoint creation. This method allows for the url to
120 be overridden to force a keystone endpoint to have specific URL for any of
121 the defined scopes (admin, internal, public).
122
123 :param configs: OSTemplateRenderer config templating object to inspect
124 for a complete https context.
125 :param url_template: str format string for creating the url template. Only
126 two values will be passed - the scheme+hostname
127 returned by the canonical_url and the port.
128 :param endpoint_type: str endpoint type to resolve.
129 :param override: str the name of the config option which overrides the
130 endpoint URL defined by the charm itself. None will
131 disable any overrides (default).
132 """
133 if override:
134 # Return any user-defined overrides for the keystone endpoint URL.
135 user_value = config(override)
136 if user_value:
137 return user_value.strip()
138
139 return url_template % (canonical_url(configs, endpoint_type), port)
140
141
142public_endpoint = partial(endpoint_url, endpoint_type=PUBLIC)
143
144internal_endpoint = partial(endpoint_url, endpoint_type=INTERNAL)
145
146admin_endpoint = partial(endpoint_url, endpoint_type=ADMIN)
147152
=== modified file 'unit_tests/test_neutron_api_hooks.py'
--- unit_tests/test_neutron_api_hooks.py 2015-04-23 08:49:03 +0000
+++ unit_tests/test_neutron_api_hooks.py 2015-06-04 23:28:32 +0000
@@ -25,7 +25,6 @@
25 'api_port',25 'api_port',
26 'apt_update',26 'apt_update',
27 'apt_install',27 'apt_install',
28 'canonical_url',
29 'config',28 'config',
30 'CONFIGS',29 'CONFIGS',
31 'check_call',30 'check_call',
@@ -319,8 +318,9 @@
319 self._call_hook('amqp-relation-broken')318 self._call_hook('amqp-relation-broken')
320 self.assertTrue(self.CONFIGS.write_all.called)319 self.assertTrue(self.CONFIGS.write_all.called)
321320
322 def test_identity_joined(self):321 @patch.object(hooks, 'canonical_url')
323 self.canonical_url.return_value = 'http://127.0.0.1'322 def test_identity_joined(self, _canonical_url):
323 _canonical_url.return_value = 'http://127.0.0.1'
324 self.api_port.return_value = '9696'324 self.api_port.return_value = '9696'
325 self.test_config.set('region', 'region1')325 self.test_config.set('region', 'region1')
326 _neutron_url = 'http://127.0.0.1:9696'326 _neutron_url = 'http://127.0.0.1:9696'
@@ -337,6 +337,34 @@
337 relation_settings=_endpoints337 relation_settings=_endpoints
338 )338 )
339339
340 @patch('charmhelpers.contrib.openstack.ip.service_name',
341 lambda *args: 'neutron-api')
342 @patch('charmhelpers.contrib.openstack.ip.unit_get')
343 @patch('charmhelpers.contrib.openstack.ip.is_clustered')
344 @patch('charmhelpers.contrib.openstack.ip.config')
345 def test_identity_changed_public_name(self, _config, _is_clustered,
346 _unit_get):
347 _unit_get.return_value = '127.0.0.1'
348 _is_clustered.return_value = False
349 _config.side_effect = self.test_config.get
350 self.api_port.return_value = '9696'
351 self.test_config.set('region', 'region1')
352 self.test_config.set('os-public-hostname',
353 'neutron-api.example.com')
354 self._call_hook('identity-service-relation-joined')
355 _neutron_url = 'http://127.0.0.1:9696'
356 _endpoints = {
357 'quantum_service': 'quantum',
358 'quantum_region': 'region1',
359 'quantum_public_url': 'http://neutron-api.example.com:9696',
360 'quantum_admin_url': _neutron_url,
361 'quantum_internal_url': _neutron_url,
362 }
363 self.relation_set.assert_called_with(
364 relation_id=None,
365 relation_settings=_endpoints
366 )
367
340 def test_identity_changed_partial_ctxt(self):368 def test_identity_changed_partial_ctxt(self):
341 self.CONFIGS.complete_contexts.return_value = []369 self.CONFIGS.complete_contexts.return_value = []
342 _api_rel_joined = self.patch('neutron_api_relation_joined')370 _api_rel_joined = self.patch('neutron_api_relation_joined')
@@ -353,12 +381,13 @@
353 self.assertTrue(self.CONFIGS.write.called_with(NEUTRON_CONF))381 self.assertTrue(self.CONFIGS.write.called_with(NEUTRON_CONF))
354 self.assertTrue(_api_rel_joined.called)382 self.assertTrue(_api_rel_joined.called)
355383
356 def test_neutron_api_relation_no_id_joined(self):384 @patch.object(hooks, 'canonical_url')
385 def test_neutron_api_relation_no_id_joined(self, _canonical_url):
357 host = 'http://127.0.0.1'386 host = 'http://127.0.0.1'
358 port = 1234387 port = 1234
359 _id_rel_joined = self.patch('identity_joined')388 _id_rel_joined = self.patch('identity_joined')
360 self.relation_ids.side_effect = self._fake_relids389 self.relation_ids.side_effect = self._fake_relids
361 self.canonical_url.return_value = host390 _canonical_url.return_value = host
362 self.api_port.return_value = port391 self.api_port.return_value = port
363 self.is_relation_made = False392 self.is_relation_made = False
364 neutron_url = '%s:%s' % (host, port)393 neutron_url = '%s:%s' % (host, port)
@@ -381,10 +410,11 @@
381 **_relation_data410 **_relation_data
382 )411 )
383412
384 def test_neutron_api_relation_joined(self):413 @patch.object(hooks, 'canonical_url')
414 def test_neutron_api_relation_joined(self, _canonical_url):
385 host = 'http://127.0.0.1'415 host = 'http://127.0.0.1'
386 port = 1234416 port = 1234
387 self.canonical_url.return_value = host417 _canonical_url.return_value = host
388 self.api_port.return_value = port418 self.api_port.return_value = port
389 self.is_relation_made = True419 self.is_relation_made = True
390 neutron_url = '%s:%s' % (host, port)420 neutron_url = '%s:%s' % (host, port)

Subscribers

People subscribed via source and target branches