Merge lp:~billy-olsen/charms/trusty/ceph-radosgw/backport-lp1398182 into lp:~openstack-charmers-archive/charms/trusty/ceph-radosgw/trunk
- Trusty Tahr (14.04)
- backport-lp1398182
- Merge into trunk
Proposed by
Billy Olsen
Status: | Merged |
---|---|
Merged at revision: | 40 |
Proposed branch: | lp:~billy-olsen/charms/trusty/ceph-radosgw/backport-lp1398182 |
Merge into: | lp:~openstack-charmers-archive/charms/trusty/ceph-radosgw/trunk |
Diff against target: |
308 lines (+106/-66) 4 files modified
config.yaml (+12/-0) hooks/charmhelpers/contrib/openstack/ip.py (+49/-44) hooks/hooks.py (+4/-15) unit_tests/test_hooks.py (+41/-7) |
To merge this branch: | bzr merge lp:~billy-olsen/charms/trusty/ceph-radosgw/backport-lp1398182 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Corey Bryant (community) | Approve | ||
Review via email: mp+262000@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote : | # |
Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_unit_test #5035 ceph-radosgw for billy-olsen mp262000
UNIT OK: passed
Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_amulet_test #4646 ceph-radosgw for billy-olsen mp262000
AMULET OK: passed
Build: http://
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
1 | === modified file 'config.yaml' |
2 | --- config.yaml 2015-01-14 13:27:02 +0000 |
3 | +++ config.yaml 2015-06-15 18:43:37 +0000 |
4 | @@ -87,3 +87,15 @@ |
5 | description: | |
6 | Default multicast port number that will be used to communicate between |
7 | HA Cluster nodes. |
8 | + os-public-hostname: |
9 | + type: string |
10 | + default: |
11 | + description: | |
12 | + The hostname or address of the public endpoints created for ceph-radosgw |
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 ceph-radosgw: |
18 | + . |
19 | + https://files.example.com:80/swift/v1 |
20 | |
21 | === modified file 'hooks/charmhelpers/contrib/openstack/ip.py' |
22 | --- hooks/charmhelpers/contrib/openstack/ip.py 2015-02-24 11:02:02 +0000 |
23 | +++ hooks/charmhelpers/contrib/openstack/ip.py 2015-06-15 18:43:37 +0000 |
24 | @@ -17,6 +17,7 @@ |
25 | from charmhelpers.core.hookenv import ( |
26 | config, |
27 | unit_get, |
28 | + service_name, |
29 | ) |
30 | from charmhelpers.contrib.network.ip import ( |
31 | get_address_in_network, |
32 | @@ -26,8 +27,6 @@ |
33 | ) |
34 | from charmhelpers.contrib.hahelpers.cluster import is_clustered |
35 | |
36 | -from functools import partial |
37 | - |
38 | PUBLIC = 'public' |
39 | INTERNAL = 'int' |
40 | ADMIN = 'admin' |
41 | @@ -35,15 +34,18 @@ |
42 | ADDRESS_MAP = { |
43 | PUBLIC: { |
44 | 'config': 'os-public-network', |
45 | - 'fallback': 'public-address' |
46 | + 'fallback': 'public-address', |
47 | + 'override': 'os-public-hostname', |
48 | }, |
49 | INTERNAL: { |
50 | 'config': 'os-internal-network', |
51 | - 'fallback': 'private-address' |
52 | + 'fallback': 'private-address', |
53 | + 'override': 'os-internal-hostname', |
54 | }, |
55 | ADMIN: { |
56 | 'config': 'os-admin-network', |
57 | - 'fallback': 'private-address' |
58 | + 'fallback': 'private-address', |
59 | + 'override': 'os-admin-hostname', |
60 | } |
61 | } |
62 | |
63 | @@ -57,15 +59,50 @@ |
64 | :param endpoint_type: str endpoint type to resolve. |
65 | :param returns: str base URL for services on the current service unit. |
66 | """ |
67 | - scheme = 'http' |
68 | - if 'https' in configs.complete_contexts(): |
69 | - scheme = 'https' |
70 | + scheme = _get_scheme(configs) |
71 | + |
72 | address = resolve_address(endpoint_type) |
73 | if is_ipv6(address): |
74 | address = "[{}]".format(address) |
75 | + |
76 | return '%s://%s' % (scheme, address) |
77 | |
78 | |
79 | +def _get_scheme(configs): |
80 | + """Returns the scheme to use for the url (either http or https) |
81 | + depending upon whether https is in the configs value. |
82 | + |
83 | + :param configs: OSTemplateRenderer config templating object to inspect |
84 | + for a complete https context. |
85 | + :returns: either 'http' or 'https' depending on whether https is |
86 | + configured within the configs context. |
87 | + """ |
88 | + scheme = 'http' |
89 | + if configs and 'https' in configs.complete_contexts(): |
90 | + scheme = 'https' |
91 | + return scheme |
92 | + |
93 | + |
94 | +def _get_address_override(endpoint_type=PUBLIC): |
95 | + """Returns any address overrides that the user has defined based on the |
96 | + endpoint type. |
97 | + |
98 | + Note: this function allows for the service name to be inserted into the |
99 | + address if the user specifies {service_name}.somehost.org. |
100 | + |
101 | + :param endpoint_type: the type of endpoint to retrieve the override |
102 | + value for. |
103 | + :returns: any endpoint address or hostname that the user has overridden |
104 | + or None if an override is not present. |
105 | + """ |
106 | + override_key = ADDRESS_MAP[endpoint_type]['override'] |
107 | + addr_override = config(override_key) |
108 | + if not addr_override: |
109 | + return None |
110 | + else: |
111 | + return addr_override.format(service_name=service_name()) |
112 | + |
113 | + |
114 | def resolve_address(endpoint_type=PUBLIC): |
115 | """Return unit address depending on net config. |
116 | |
117 | @@ -77,7 +114,10 @@ |
118 | |
119 | :param endpoint_type: Network endpoing type |
120 | """ |
121 | - resolved_address = None |
122 | + resolved_address = _get_address_override(endpoint_type) |
123 | + if resolved_address: |
124 | + return resolved_address |
125 | + |
126 | vips = config('vip') |
127 | if vips: |
128 | vips = vips.split() |
129 | @@ -109,38 +149,3 @@ |
130 | "clustered=%s)" % (net_type, clustered)) |
131 | |
132 | return resolved_address |
133 | - |
134 | - |
135 | -def endpoint_url(configs, url_template, port, endpoint_type=PUBLIC, |
136 | - override=None): |
137 | - """Returns the correct endpoint URL to advertise to Keystone. |
138 | - |
139 | - This method provides the correct endpoint URL which should be advertised to |
140 | - the keystone charm for endpoint creation. This method allows for the url to |
141 | - be overridden to force a keystone endpoint to have specific URL for any of |
142 | - the defined scopes (admin, internal, public). |
143 | - |
144 | - :param configs: OSTemplateRenderer config templating object to inspect |
145 | - for a complete https context. |
146 | - :param url_template: str format string for creating the url template. Only |
147 | - two values will be passed - the scheme+hostname |
148 | - returned by the canonical_url and the port. |
149 | - :param endpoint_type: str endpoint type to resolve. |
150 | - :param override: str the name of the config option which overrides the |
151 | - endpoint URL defined by the charm itself. None will |
152 | - disable any overrides (default). |
153 | - """ |
154 | - if override: |
155 | - # Return any user-defined overrides for the keystone endpoint URL. |
156 | - user_value = config(override) |
157 | - if user_value: |
158 | - return user_value.strip() |
159 | - |
160 | - return url_template % (canonical_url(configs, endpoint_type), port) |
161 | - |
162 | - |
163 | -public_endpoint = partial(endpoint_url, endpoint_type=PUBLIC) |
164 | - |
165 | -internal_endpoint = partial(endpoint_url, endpoint_type=INTERNAL) |
166 | - |
167 | -admin_endpoint = partial(endpoint_url, endpoint_type=ADMIN) |
168 | |
169 | === modified file 'hooks/hooks.py' |
170 | --- hooks/hooks.py 2015-04-28 21:18:24 +0000 |
171 | +++ hooks/hooks.py 2015-06-15 18:43:37 +0000 |
172 | @@ -50,10 +50,9 @@ |
173 | from charmhelpers.contrib.network.ip import ( |
174 | get_iface_for_address, |
175 | get_netmask_for_address, |
176 | - is_ipv6, |
177 | ) |
178 | from charmhelpers.contrib.openstack.ip import ( |
179 | - resolve_address, |
180 | + canonical_url, |
181 | PUBLIC, INTERNAL, ADMIN, |
182 | ) |
183 | |
184 | @@ -273,16 +272,6 @@ |
185 | open_port(port=80) |
186 | |
187 | |
188 | -# XXX Define local canonical_url until charm has been updated to use the |
189 | -# standard context architecture. |
190 | -def canonical_url(configs, endpoint_type=PUBLIC): |
191 | - scheme = 'http' |
192 | - address = resolve_address(endpoint_type) |
193 | - if is_ipv6(address): |
194 | - address = "[{}]".format(address) |
195 | - return '%s://%s' % (scheme, address) |
196 | - |
197 | - |
198 | @hooks.hook('identity-service-relation-joined') |
199 | def identity_joined(relid=None): |
200 | if cmp_pkgrevno('radosgw', '0.55') < 0: |
201 | @@ -290,11 +279,11 @@ |
202 | sys.exit(1) |
203 | |
204 | port = 80 |
205 | - admin_url = '%s:%i/swift' % (canonical_url(ADMIN), port) |
206 | + admin_url = '%s:%i/swift' % (canonical_url(None, ADMIN), port) |
207 | internal_url = '%s:%s/swift/v1' % \ |
208 | - (canonical_url(INTERNAL), port) |
209 | + (canonical_url(None, INTERNAL), port) |
210 | public_url = '%s:%s/swift/v1' % \ |
211 | - (canonical_url(PUBLIC), port) |
212 | + (canonical_url(None, PUBLIC), port) |
213 | relation_set(service='swift', |
214 | region=config('region'), |
215 | public_url=public_url, internal_url=internal_url, |
216 | |
217 | === modified file 'unit_tests/test_hooks.py' |
218 | --- unit_tests/test_hooks.py 2015-04-28 21:18:24 +0000 |
219 | +++ unit_tests/test_hooks.py 2015-06-15 18:43:37 +0000 |
220 | @@ -8,6 +8,7 @@ |
221 | CharmTestCase, |
222 | patch_open |
223 | ) |
224 | +from charmhelpers.contrib.openstack.ip import PUBLIC |
225 | |
226 | dnsmock = MagicMock() |
227 | modules = { |
228 | @@ -45,7 +46,6 @@ |
229 | 'relation_set', |
230 | 'relation_get', |
231 | 'render_template', |
232 | - 'resolve_address', |
233 | 'shutil', |
234 | 'subprocess', |
235 | 'sys', |
236 | @@ -323,14 +323,22 @@ |
237 | cmd = ['service', 'radosgw', 'restart'] |
238 | self.subprocess.call.assert_called_with(cmd) |
239 | |
240 | - def test_identity_joined_early_version(self): |
241 | + @patch('charmhelpers.contrib.openstack.ip.service_name', |
242 | + lambda *args: 'ceph-radosgw') |
243 | + @patch('charmhelpers.contrib.openstack.ip.config') |
244 | + def test_identity_joined_early_version(self, _config): |
245 | self.cmp_pkgrevno.return_value = -1 |
246 | ceph_hooks.identity_joined() |
247 | self.sys.exit.assert_called_with(1) |
248 | |
249 | - def test_identity_joined(self): |
250 | + @patch('charmhelpers.contrib.openstack.ip.service_name', |
251 | + lambda *args: 'ceph-radosgw') |
252 | + @patch('charmhelpers.contrib.openstack.ip.resolve_address') |
253 | + @patch('charmhelpers.contrib.openstack.ip.config') |
254 | + def test_identity_joined(self, _config, _resolve_address): |
255 | self.cmp_pkgrevno.return_value = 1 |
256 | - self.resolve_address.return_value = 'myserv' |
257 | + _resolve_address.return_value = 'myserv' |
258 | + _config.side_effect = self.test_config.get |
259 | self.test_config.set('region', 'region1') |
260 | self.test_config.set('operator-roles', 'admin') |
261 | self.unit_get.return_value = 'myserv' |
262 | @@ -344,6 +352,27 @@ |
263 | relation_id='rid', |
264 | admin_url='http://myserv:80/swift') |
265 | |
266 | + @patch('charmhelpers.contrib.openstack.ip.service_name', |
267 | + lambda *args: 'ceph-radosgw') |
268 | + @patch('charmhelpers.contrib.openstack.ip.is_clustered') |
269 | + @patch('charmhelpers.contrib.openstack.ip.unit_get') |
270 | + @patch('charmhelpers.contrib.openstack.ip.config') |
271 | + def test_identity_joined_public_name(self, _config, _unit_get, |
272 | + _is_clustered): |
273 | + _config.side_effect = self.test_config.get |
274 | + self.test_config.set('os-public-hostname', 'files.example.com') |
275 | + _unit_get.return_value = 'myserv' |
276 | + _is_clustered.return_value = False |
277 | + ceph_hooks.identity_joined(relid='rid') |
278 | + self.relation_set.assert_called_with( |
279 | + service='swift', |
280 | + region='RegionOne', |
281 | + public_url='http://files.example.com:80/swift/v1', |
282 | + internal_url='http://myserv:80/swift/v1', |
283 | + requested_roles='Member,Admin', |
284 | + relation_id='rid', |
285 | + admin_url='http://myserv:80/swift') |
286 | + |
287 | def test_identity_changed(self): |
288 | _emit_cephconf = self.patch('emit_cephconf') |
289 | _restart = self.patch('restart') |
290 | @@ -351,10 +380,15 @@ |
291 | _emit_cephconf.assert_called() |
292 | _restart.assert_called() |
293 | |
294 | - def test_canonical_url_ipv6(self): |
295 | + @patch('charmhelpers.contrib.openstack.ip.is_clustered') |
296 | + @patch('charmhelpers.contrib.openstack.ip.unit_get') |
297 | + @patch('charmhelpers.contrib.openstack.ip.config') |
298 | + def test_canonical_url_ipv6(self, _config, _unit_get, _is_clustered): |
299 | ipv6_addr = '2001:db8:85a3:8d3:1319:8a2e:370:7348' |
300 | - self.resolve_address.return_value = ipv6_addr |
301 | - self.assertEquals(ceph_hooks.canonical_url({}), |
302 | + _config.side_effect = self.test_config.get |
303 | + _unit_get.return_value = ipv6_addr |
304 | + _is_clustered.return_value = False |
305 | + self.assertEquals(ceph_hooks.canonical_url({}, PUBLIC), |
306 | 'http://[%s]' % ipv6_addr) |
307 | |
308 | @patch.object(ceph_hooks, 'CONFIGS') |
charm_lint_check #5403 ceph-radosgw for billy-olsen mp262000
LINT OK: passed
Build: http:// 10.245. 162.77: 8080/job/ charm_lint_ check/5403/