Merge lp:~billy-olsen/charm-helpers/better-address-endpoint-overrides into lp:charm-helpers

Proposed by Billy Olsen
Status: Superseded
Proposed branch: lp:~billy-olsen/charm-helpers/better-address-endpoint-overrides
Merge into: lp:charm-helpers
Diff against target: 165 lines (+39/-71)
2 files modified
charmhelpers/contrib/openstack/ip.py (+32/-43)
tests/contrib/openstack/test_ip.py (+7/-28)
To merge this branch: bzr merge lp:~billy-olsen/charm-helpers/better-address-endpoint-overrides
Reviewer Review Type Date Requested Status
Edward Hope-Morley Pending
charmers Pending
Review via email: mp+260616@code.launchpad.net

This proposal has been superseded by a proposal from 2015-06-03.

To post a comment you must log in.
383. By Billy Olsen

After studying the code across the OpenStack charms, it seems a better
place for the override is to place it in the canonical_url method. This
has the advantage of capturing more places besides endpoint URLs (e.g.
also for console hosts etc) and requires fewer changes to most of the
OpenStack charms.

384. By Billy Olsen

Move public address override into resolve_address.

385. By Billy Olsen

Allow configs to be None and default to http if it isn't found
for the protocol scheme

386. By Billy Olsen

Switch config option to os-public-hostname

387. By Billy Olsen

Add templating to the os-public-hostname override per jjo's bug comment.

388. By Billy Olsen

Per niedbalski's review remove jinja2 dependency and use simple string
formatting. Additionally break out the override check into its own
function.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'charmhelpers/contrib/openstack/ip.py'
2--- charmhelpers/contrib/openstack/ip.py 2015-02-12 22:30:09 +0000
3+++ charmhelpers/contrib/openstack/ip.py 2015-06-03 18:18:45 +0000
4@@ -26,8 +26,6 @@
5 )
6 from charmhelpers.contrib.hahelpers.cluster import is_clustered
7
8-from functools import partial
9-
10 PUBLIC = 'public'
11 INTERNAL = 'int'
12 ADMIN = 'admin'
13@@ -35,15 +33,18 @@
14 ADDRESS_MAP = {
15 PUBLIC: {
16 'config': 'os-public-network',
17- 'fallback': 'public-address'
18+ 'fallback': 'public-address',
19+ 'override': 'os-public-hostname',
20 },
21 INTERNAL: {
22 'config': 'os-internal-network',
23- 'fallback': 'private-address'
24+ 'fallback': 'private-address',
25+ 'override': 'os-internal-hostname',
26 },
27 ADMIN: {
28 'config': 'os-admin-network',
29- 'fallback': 'private-address'
30+ 'fallback': 'private-address',
31+ 'override': 'os-admin-hostname',
32 }
33 }
34
35@@ -57,15 +58,30 @@
36 :param endpoint_type: str endpoint type to resolve.
37 :param returns: str base URL for services on the current service unit.
38 """
39- scheme = 'http'
40- if 'https' in configs.complete_contexts():
41- scheme = 'https'
42+ scheme = _get_scheme(configs)
43+
44 address = resolve_address(endpoint_type)
45 if is_ipv6(address):
46 address = "[{}]".format(address)
47+
48 return '%s://%s' % (scheme, address)
49
50
51+def _get_scheme(configs):
52+ """Returns the scheme to use for the url (either http or https)
53+ depending upon whether https is in the configs value.
54+
55+ :param configs: OSTemplateRenderer config templating object to inspect
56+ for a complete https context.
57+ :returns: either 'http' or 'https' depending on whether https is
58+ configured within the configs context.
59+ """
60+ scheme = 'http'
61+ if configs and 'https' in configs.complete_contexts():
62+ scheme = 'https'
63+ return scheme
64+
65+
66 def resolve_address(endpoint_type=PUBLIC):
67 """Return unit address depending on net config.
68
69@@ -78,6 +94,14 @@
70 :param endpoint_type: Network endpoing type
71 """
72 resolved_address = None
73+
74+ # Allow the user to override the address which is used. This is
75+ # useful for proxy services or exposing a public endpoint url, etc.
76+ override_key = ADDRESS_MAP[endpoint_type]['override']
77+ addr_override = config(override_key)
78+ if addr_override:
79+ return addr_override
80+
81 vips = config('vip')
82 if vips:
83 vips = vips.split()
84@@ -109,38 +133,3 @@
85 "clustered=%s)" % (net_type, clustered))
86
87 return resolved_address
88-
89-
90-def endpoint_url(configs, url_template, port, endpoint_type=PUBLIC,
91- override=None):
92- """Returns the correct endpoint URL to advertise to Keystone.
93-
94- This method provides the correct endpoint URL which should be advertised to
95- the keystone charm for endpoint creation. This method allows for the url to
96- be overridden to force a keystone endpoint to have specific URL for any of
97- the defined scopes (admin, internal, public).
98-
99- :param configs: OSTemplateRenderer config templating object to inspect
100- for a complete https context.
101- :param url_template: str format string for creating the url template. Only
102- two values will be passed - the scheme+hostname
103- returned by the canonical_url and the port.
104- :param endpoint_type: str endpoint type to resolve.
105- :param override: str the name of the config option which overrides the
106- endpoint URL defined by the charm itself. None will
107- disable any overrides (default).
108- """
109- if override:
110- # Return any user-defined overrides for the keystone endpoint URL.
111- user_value = config(override)
112- if user_value:
113- return user_value.strip()
114-
115- return url_template % (canonical_url(configs, endpoint_type), port)
116-
117-
118-public_endpoint = partial(endpoint_url, endpoint_type=PUBLIC)
119-
120-internal_endpoint = partial(endpoint_url, endpoint_type=INTERNAL)
121-
122-admin_endpoint = partial(endpoint_url, endpoint_type=ADMIN)
123
124=== modified file 'tests/contrib/openstack/test_ip.py'
125--- tests/contrib/openstack/test_ip.py 2015-02-12 22:30:09 +0000
126+++ tests/contrib/openstack/test_ip.py 2015-06-03 18:18:45 +0000
127@@ -110,31 +110,10 @@
128 self.assertTrue(ip.canonical_url(configs),
129 'https://unit1')
130
131- def test_endpoint_url(self):
132- exp_url = 'https://public.example.com'
133- self.test_config.set('public-url', exp_url)
134- configs = MagicMock()
135- configs.complete_contexts.return_value = ['https']
136- endpoint = ip.endpoint_url(configs, '%s:%s', 443, ip.PUBLIC,
137- 'public-url')
138- self.assertEqual(exp_url, endpoint)
139-
140- @patch.object(ip, 'resolve_address')
141- def test_endpoint_url_no_override(self, resolve_address):
142- resolve_address.return_value = 'unit1'
143- configs = MagicMock()
144- configs.complete_contexts.return_value = ['https']
145- endpoint = ip.endpoint_url(configs, '%s:%s/v1/AUTH_$(tenant_id)s', 443,
146- ip.INTERNAL, 'internal-url')
147- self.assertEqual('https://unit1:443/v1/AUTH_$(tenant_id)s', endpoint)
148-
149- @patch.object(ip, 'resolve_address')
150- @patch.object(ip, 'is_ipv6')
151- def test_endpoint_url_no_override_ipv6(self, is_ipv6, resolve_address):
152- resolve_address.return_value = 'unit1'
153- is_ipv6.return_value = True
154- configs = MagicMock()
155- configs.complete_contexts.return_value = ['https']
156- endpoint = ip.endpoint_url(configs, '%s:%s', 443,
157- ip.ADMIN, 'admin-url')
158- self.assertEquals('https://[unit1]:443', endpoint)
159+ def test_canonical_url_override(self):
160+ configs = MagicMock()
161+ configs.complete_contexts.return_value = ['https']
162+ self.test_config.set('os-public-hostname', 'public.example.com')
163+ endpoint = ip.canonical_url(configs)
164+ self.assertEqual('https://public.example.com',
165+ endpoint)

Subscribers

People subscribed via source and target branches