Merge lp:~billy-olsen/charms/trusty/swift-proxy/public-endpoint-host into lp:~openstack-charmers-archive/charms/trusty/swift-proxy/next
- Trusty Tahr (14.04)
- public-endpoint-host
- Merge into next
Status: | Merged |
---|---|
Merged at revision: | 98 |
Proposed branch: | lp:~billy-olsen/charms/trusty/swift-proxy/public-endpoint-host |
Merge into: | lp:~openstack-charmers-archive/charms/trusty/swift-proxy/next |
Diff against target: |
291 lines (+155/-48) 3 files modified
config.yaml (+12/-0) hooks/charmhelpers/contrib/openstack/ip.py (+49/-44) unit_tests/test_swift_hooks.py (+94/-4) |
To merge this branch: | bzr merge lp:~billy-olsen/charms/trusty/swift-proxy/public-endpoint-host |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Corey Bryant (community) | Approve | ||
Review via email: mp+261005@code.launchpad.net |
Commit message
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.
uosci-testing-bot (uosci-testing-bot) wrote : | # |
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_unit_test #4723 swift-proxy-next for billy-olsen mp261005
UNIT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_amulet_test #4449 swift-proxy-next for billy-olsen mp261005
AMULET OK: passed
Build: http://
- 99. By Billy Olsen
-
c-h sync
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_lint_check #5074 swift-proxy-next for billy-olsen mp261005
LINT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_unit_test #4753 swift-proxy-next for billy-olsen mp261005
UNIT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_amulet_test #4481 swift-proxy-next for billy-olsen mp261005
AMULET OK: passed
Build: http://
Corey Bryant (corey.bryant) wrote : | # |
Looks good! Mind adding a unit test?
- 100. By Billy Olsen
-
Add unit test for public hostname.
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_lint_check #5344 swift-proxy-next for billy-olsen mp261005
LINT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_unit_test #4976 swift-proxy-next for billy-olsen mp261005
UNIT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_amulet_test #4585 swift-proxy-next for billy-olsen mp261005
AMULET OK: passed
Build: http://
Corey Bryant (corey.bryant) : | # |
Preview Diff
1 | === modified file 'config.yaml' |
2 | --- config.yaml 2015-04-20 11:19:04 +0000 |
3 | +++ config.yaml 2015-06-11 23:23:30 +0000 |
4 | @@ -207,6 +207,18 @@ |
5 | 192.168.0.0/24) |
6 | . |
7 | This network will be used for public endpoints. |
8 | + os-public-hostname: |
9 | + type: string |
10 | + default: |
11 | + description: | |
12 | + The hostname or address of the public endpoints created for swift-proxy |
13 | + in the keystone identity provider. |
14 | + . |
15 | + This value will be used for public endpoints. For example, an |
16 | + os-public-hostname set to 'files.example.com' with will create |
17 | + the following public endpoint for the swift-proxy: |
18 | + . |
19 | + https://files.example.com:80/swift/v1 |
20 | prefer-ipv6: |
21 | type: boolean |
22 | default: False |
23 | |
24 | === modified file 'hooks/charmhelpers/contrib/hahelpers/cluster.py' |
25 | === modified file 'hooks/charmhelpers/contrib/openstack/ip.py' |
26 | --- hooks/charmhelpers/contrib/openstack/ip.py 2015-03-13 13:02:08 +0000 |
27 | +++ hooks/charmhelpers/contrib/openstack/ip.py 2015-06-11 23:23:30 +0000 |
28 | @@ -17,6 +17,7 @@ |
29 | from charmhelpers.core.hookenv import ( |
30 | config, |
31 | unit_get, |
32 | + service_name, |
33 | ) |
34 | from charmhelpers.contrib.network.ip import ( |
35 | get_address_in_network, |
36 | @@ -26,8 +27,6 @@ |
37 | ) |
38 | from charmhelpers.contrib.hahelpers.cluster import is_clustered |
39 | |
40 | -from functools import partial |
41 | - |
42 | PUBLIC = 'public' |
43 | INTERNAL = 'int' |
44 | ADMIN = 'admin' |
45 | @@ -35,15 +34,18 @@ |
46 | ADDRESS_MAP = { |
47 | PUBLIC: { |
48 | 'config': 'os-public-network', |
49 | - 'fallback': 'public-address' |
50 | + 'fallback': 'public-address', |
51 | + 'override': 'os-public-hostname', |
52 | }, |
53 | INTERNAL: { |
54 | 'config': 'os-internal-network', |
55 | - 'fallback': 'private-address' |
56 | + 'fallback': 'private-address', |
57 | + 'override': 'os-internal-hostname', |
58 | }, |
59 | ADMIN: { |
60 | 'config': 'os-admin-network', |
61 | - 'fallback': 'private-address' |
62 | + 'fallback': 'private-address', |
63 | + 'override': 'os-admin-hostname', |
64 | } |
65 | } |
66 | |
67 | @@ -57,15 +59,50 @@ |
68 | :param endpoint_type: str endpoint type to resolve. |
69 | :param returns: str base URL for services on the current service unit. |
70 | """ |
71 | - scheme = 'http' |
72 | - if 'https' in configs.complete_contexts(): |
73 | - scheme = 'https' |
74 | + scheme = _get_scheme(configs) |
75 | + |
76 | address = resolve_address(endpoint_type) |
77 | if is_ipv6(address): |
78 | address = "[{}]".format(address) |
79 | + |
80 | return '%s://%s' % (scheme, address) |
81 | |
82 | |
83 | +def _get_scheme(configs): |
84 | + """Returns the scheme to use for the url (either http or https) |
85 | + depending upon whether https is in the configs value. |
86 | + |
87 | + :param configs: OSTemplateRenderer config templating object to inspect |
88 | + for a complete https context. |
89 | + :returns: either 'http' or 'https' depending on whether https is |
90 | + configured within the configs context. |
91 | + """ |
92 | + scheme = 'http' |
93 | + if configs and 'https' in configs.complete_contexts(): |
94 | + scheme = 'https' |
95 | + return scheme |
96 | + |
97 | + |
98 | +def _get_address_override(endpoint_type=PUBLIC): |
99 | + """Returns any address overrides that the user has defined based on the |
100 | + endpoint type. |
101 | + |
102 | + Note: this function allows for the service name to be inserted into the |
103 | + address if the user specifies {service_name}.somehost.org. |
104 | + |
105 | + :param endpoint_type: the type of endpoint to retrieve the override |
106 | + value for. |
107 | + :returns: any endpoint address or hostname that the user has overridden |
108 | + or None if an override is not present. |
109 | + """ |
110 | + override_key = ADDRESS_MAP[endpoint_type]['override'] |
111 | + addr_override = config(override_key) |
112 | + if not addr_override: |
113 | + return None |
114 | + else: |
115 | + return addr_override.format(service_name=service_name()) |
116 | + |
117 | + |
118 | def resolve_address(endpoint_type=PUBLIC): |
119 | """Return unit address depending on net config. |
120 | |
121 | @@ -77,7 +114,10 @@ |
122 | |
123 | :param endpoint_type: Network endpoing type |
124 | """ |
125 | - resolved_address = None |
126 | + resolved_address = _get_address_override(endpoint_type) |
127 | + if resolved_address: |
128 | + return resolved_address |
129 | + |
130 | vips = config('vip') |
131 | if vips: |
132 | vips = vips.split() |
133 | @@ -109,38 +149,3 @@ |
134 | "clustered=%s)" % (net_type, clustered)) |
135 | |
136 | return resolved_address |
137 | - |
138 | - |
139 | -def endpoint_url(configs, url_template, port, endpoint_type=PUBLIC, |
140 | - override=None): |
141 | - """Returns the correct endpoint URL to advertise to Keystone. |
142 | - |
143 | - This method provides the correct endpoint URL which should be advertised to |
144 | - the keystone charm for endpoint creation. This method allows for the url to |
145 | - be overridden to force a keystone endpoint to have specific URL for any of |
146 | - the defined scopes (admin, internal, public). |
147 | - |
148 | - :param configs: OSTemplateRenderer config templating object to inspect |
149 | - for a complete https context. |
150 | - :param url_template: str format string for creating the url template. Only |
151 | - two values will be passed - the scheme+hostname |
152 | - returned by the canonical_url and the port. |
153 | - :param endpoint_type: str endpoint type to resolve. |
154 | - :param override: str the name of the config option which overrides the |
155 | - endpoint URL defined by the charm itself. None will |
156 | - disable any overrides (default). |
157 | - """ |
158 | - if override: |
159 | - # Return any user-defined overrides for the keystone endpoint URL. |
160 | - user_value = config(override) |
161 | - if user_value: |
162 | - return user_value.strip() |
163 | - |
164 | - return url_template % (canonical_url(configs, endpoint_type), port) |
165 | - |
166 | - |
167 | -public_endpoint = partial(endpoint_url, endpoint_type=PUBLIC) |
168 | - |
169 | -internal_endpoint = partial(endpoint_url, endpoint_type=INTERNAL) |
170 | - |
171 | -admin_endpoint = partial(endpoint_url, endpoint_type=ADMIN) |
172 | |
173 | === modified file 'hooks/charmhelpers/contrib/peerstorage/__init__.py' |
174 | === modified file 'unit_tests/test_swift_hooks.py' |
175 | --- unit_tests/test_swift_hooks.py 2014-12-05 13:21:52 +0000 |
176 | +++ unit_tests/test_swift_hooks.py 2015-06-11 23:23:30 +0000 |
177 | @@ -1,16 +1,16 @@ |
178 | -import mock |
179 | +from mock import patch |
180 | import unittest |
181 | import uuid |
182 | |
183 | |
184 | -with mock.patch('charmhelpers.core.hookenv.log'): |
185 | +with patch('charmhelpers.core.hookenv.log'): |
186 | import swift_hooks |
187 | |
188 | |
189 | class SwiftHooksTestCase(unittest.TestCase): |
190 | |
191 | - @mock.patch("swift_hooks.relation_get") |
192 | - @mock.patch("swift_hooks.local_unit") |
193 | + @patch("swift_hooks.relation_get") |
194 | + @patch("swift_hooks.local_unit") |
195 | def test_all_peers_stopped(self, mock_local_unit, mock_relation_get): |
196 | token1 = str(uuid.uuid4()) |
197 | token2 = str(uuid.uuid4()) |
198 | @@ -37,3 +37,93 @@ |
199 | responses = [{'stop-proxy-service-ack': token1}, |
200 | {'stop-proxy-service-ack': token1}] |
201 | self.assertFalse(swift_hooks.all_peers_stopped(responses)) |
202 | + |
203 | + @patch.object(swift_hooks, 'config') |
204 | + @patch('charmhelpers.contrib.openstack.ip.config') |
205 | + @patch.object(swift_hooks, 'CONFIGS') |
206 | + @patch('charmhelpers.core.hookenv.local_unit') |
207 | + @patch('charmhelpers.core.hookenv.service_name') |
208 | + @patch('charmhelpers.contrib.openstack.ip.unit_get') |
209 | + @patch('charmhelpers.contrib.openstack.ip.is_clustered') |
210 | + @patch.object(swift_hooks, 'relation_set') |
211 | + def test_keystone_joined(self, _relation_set, _is_clustered, _unit_get, |
212 | + _service_name, _local_unit, _CONFIGS, _ip_config, |
213 | + _config): |
214 | + config_dict = { |
215 | + 'bind-port': '1234', |
216 | + 'region': 'RegionOne', |
217 | + 'operator-roles': 'Operator,Monitor' |
218 | + } |
219 | + |
220 | + def foo(key=None): |
221 | + if key is None: |
222 | + return config_dict |
223 | + else: |
224 | + return config_dict.get(key) |
225 | + |
226 | + _config.side_effect = foo |
227 | + _ip_config.side_effect = foo |
228 | + _unit_get.return_value = 'swift-proxy' |
229 | + _local_unit.return_value = 'swift-proxy/0' |
230 | + _service_name.return_value = 'swift-proxy' |
231 | + _is_clustered.return_value = False |
232 | + |
233 | + swift_hooks.keystone_joined() |
234 | + |
235 | + _relation_set.assert_called_with( |
236 | + service='swift', |
237 | + region='RegionOne', |
238 | + public_url='http://swift-proxy:1234/v1/AUTH_$(tenant_id)s', |
239 | + internal_url='http://swift-proxy:1234/v1/AUTH_$(tenant_id)s', |
240 | + admin_url='http://swift-proxy:1234', |
241 | + requested_roles='Operator,Monitor', |
242 | + relation_id=None |
243 | + ) |
244 | + |
245 | + @patch.object(swift_hooks, 'config') |
246 | + @patch('charmhelpers.contrib.openstack.ip.config') |
247 | + @patch.object(swift_hooks, 'CONFIGS') |
248 | + @patch('charmhelpers.core.hookenv.local_unit') |
249 | + @patch('charmhelpers.core.hookenv.service_name') |
250 | + @patch('charmhelpers.contrib.openstack.ip.unit_get') |
251 | + @patch('charmhelpers.contrib.openstack.ip.is_clustered') |
252 | + @patch.object(swift_hooks, 'relation_set') |
253 | + def test_keystone_joined_public_hostname(self, |
254 | + _relation_set, |
255 | + _is_clustered, |
256 | + _unit_get, |
257 | + _service_name, |
258 | + _local_unit, |
259 | + _CONFIGS, |
260 | + _ip_config, |
261 | + _config): |
262 | + config_dict = { |
263 | + 'bind-port': '1234', |
264 | + 'region': 'RegionOne', |
265 | + 'operator-roles': 'Operator,Monitor', |
266 | + 'os-public-hostname': 'public.example.com' |
267 | + } |
268 | + |
269 | + def foo(key=None): |
270 | + if key is None: |
271 | + return config_dict |
272 | + else: |
273 | + return config_dict.get(key) |
274 | + |
275 | + _config.side_effect = _ip_config.side_effect = foo |
276 | + _unit_get.return_value = _service_name.return_value = 'swift-proxy' |
277 | + _local_unit.return_value = 'swift-proxy/0' |
278 | + _is_clustered.return_value = False |
279 | + |
280 | + swift_hooks.keystone_joined() |
281 | + |
282 | + _relation_set.assert_called_with( |
283 | + service='swift', |
284 | + region='RegionOne', |
285 | + public_url=('http://public.example.com:1234/' |
286 | + 'v1/AUTH_$(tenant_id)s'), |
287 | + internal_url='http://swift-proxy:1234/v1/AUTH_$(tenant_id)s', |
288 | + admin_url='http://swift-proxy:1234', |
289 | + requested_roles='Operator,Monitor', |
290 | + relation_id=None |
291 | + ) |
charm_lint_check #5043 swift-proxy-next for billy-olsen mp261005
LINT OK: passed
Build: http:// 10.245. 162.77: 8080/job/ charm_lint_ check/5043/