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
=== modified file 'charmhelpers/contrib/openstack/ip.py'
--- charmhelpers/contrib/openstack/ip.py 2015-02-12 22:30:09 +0000
+++ charmhelpers/contrib/openstack/ip.py 2015-06-03 18:18:45 +0000
@@ -26,8 +26,6 @@
26)26)
27from charmhelpers.contrib.hahelpers.cluster import is_clustered27from charmhelpers.contrib.hahelpers.cluster import is_clustered
2828
29from functools import partial
30
31PUBLIC = 'public'29PUBLIC = 'public'
32INTERNAL = 'int'30INTERNAL = 'int'
33ADMIN = 'admin'31ADMIN = 'admin'
@@ -35,15 +33,18 @@
35ADDRESS_MAP = {33ADDRESS_MAP = {
36 PUBLIC: {34 PUBLIC: {
37 'config': 'os-public-network',35 'config': 'os-public-network',
38 'fallback': 'public-address'36 'fallback': 'public-address',
37 'override': 'os-public-hostname',
39 },38 },
40 INTERNAL: {39 INTERNAL: {
41 'config': 'os-internal-network',40 'config': 'os-internal-network',
42 'fallback': 'private-address'41 'fallback': 'private-address',
42 'override': 'os-internal-hostname',
43 },43 },
44 ADMIN: {44 ADMIN: {
45 'config': 'os-admin-network',45 'config': 'os-admin-network',
46 'fallback': 'private-address'46 'fallback': 'private-address',
47 'override': 'os-admin-hostname',
47 }48 }
48}49}
4950
@@ -57,15 +58,30 @@
57 :param endpoint_type: str endpoint type to resolve.58 :param endpoint_type: str endpoint type to resolve.
58 :param returns: str base URL for services on the current service unit.59 :param returns: str base URL for services on the current service unit.
59 """60 """
60 scheme = 'http'61 scheme = _get_scheme(configs)
61 if 'https' in configs.complete_contexts():62
62 scheme = 'https'
63 address = resolve_address(endpoint_type)63 address = resolve_address(endpoint_type)
64 if is_ipv6(address):64 if is_ipv6(address):
65 address = "[{}]".format(address)65 address = "[{}]".format(address)
66
66 return '%s://%s' % (scheme, address)67 return '%s://%s' % (scheme, address)
6768
6869
70def _get_scheme(configs):
71 """Returns the scheme to use for the url (either http or https)
72 depending upon whether https is in the configs value.
73
74 :param configs: OSTemplateRenderer config templating object to inspect
75 for a complete https context.
76 :returns: either 'http' or 'https' depending on whether https is
77 configured within the configs context.
78 """
79 scheme = 'http'
80 if configs and 'https' in configs.complete_contexts():
81 scheme = 'https'
82 return scheme
83
84
69def resolve_address(endpoint_type=PUBLIC):85def resolve_address(endpoint_type=PUBLIC):
70 """Return unit address depending on net config.86 """Return unit address depending on net config.
7187
@@ -78,6 +94,14 @@
78 :param endpoint_type: Network endpoing type94 :param endpoint_type: Network endpoing type
79 """95 """
80 resolved_address = None96 resolved_address = None
97
98 # Allow the user to override the address which is used. This is
99 # useful for proxy services or exposing a public endpoint url, etc.
100 override_key = ADDRESS_MAP[endpoint_type]['override']
101 addr_override = config(override_key)
102 if addr_override:
103 return addr_override
104
81 vips = config('vip')105 vips = config('vip')
82 if vips:106 if vips:
83 vips = vips.split()107 vips = vips.split()
@@ -109,38 +133,3 @@
109 "clustered=%s)" % (net_type, clustered))133 "clustered=%s)" % (net_type, clustered))
110134
111 return resolved_address135 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)
147136
=== modified file 'tests/contrib/openstack/test_ip.py'
--- tests/contrib/openstack/test_ip.py 2015-02-12 22:30:09 +0000
+++ tests/contrib/openstack/test_ip.py 2015-06-03 18:18:45 +0000
@@ -110,31 +110,10 @@
110 self.assertTrue(ip.canonical_url(configs),110 self.assertTrue(ip.canonical_url(configs),
111 'https://unit1')111 'https://unit1')
112112
113 def test_endpoint_url(self):113 def test_canonical_url_override(self):
114 exp_url = 'https://public.example.com'114 configs = MagicMock()
115 self.test_config.set('public-url', exp_url)115 configs.complete_contexts.return_value = ['https']
116 configs = MagicMock()116 self.test_config.set('os-public-hostname', 'public.example.com')
117 configs.complete_contexts.return_value = ['https']117 endpoint = ip.canonical_url(configs)
118 endpoint = ip.endpoint_url(configs, '%s:%s', 443, ip.PUBLIC,118 self.assertEqual('https://public.example.com',
119 'public-url')119 endpoint)
120 self.assertEqual(exp_url, endpoint)
121
122 @patch.object(ip, 'resolve_address')
123 def test_endpoint_url_no_override(self, resolve_address):
124 resolve_address.return_value = 'unit1'
125 configs = MagicMock()
126 configs.complete_contexts.return_value = ['https']
127 endpoint = ip.endpoint_url(configs, '%s:%s/v1/AUTH_$(tenant_id)s', 443,
128 ip.INTERNAL, 'internal-url')
129 self.assertEqual('https://unit1:443/v1/AUTH_$(tenant_id)s', endpoint)
130
131 @patch.object(ip, 'resolve_address')
132 @patch.object(ip, 'is_ipv6')
133 def test_endpoint_url_no_override_ipv6(self, is_ipv6, resolve_address):
134 resolve_address.return_value = 'unit1'
135 is_ipv6.return_value = True
136 configs = MagicMock()
137 configs.complete_contexts.return_value = ['https']
138 endpoint = ip.endpoint_url(configs, '%s:%s', 443,
139 ip.ADMIN, 'admin-url')
140 self.assertEquals('https://[unit1]:443', endpoint)

Subscribers

People subscribed via source and target branches