Merge lp:~hopem/charms/trusty/percona-cluster/fix-1389670 into lp:~openstack-charmers-archive/charms/trusty/percona-cluster/trunk
- Trusty Tahr (14.04)
- fix-1389670
- Merge into trunk
Proposed by
Edward Hope-Morley
Status: | Merged |
---|---|
Merged at revision: | 43 |
Proposed branch: | lp:~hopem/charms/trusty/percona-cluster/fix-1389670 |
Merge into: | lp:~openstack-charmers-archive/charms/trusty/percona-cluster/trunk |
Diff against target: |
325 lines (+115/-87) 4 files modified
hooks/mysql.py (+30/-28) hooks/percona_hooks.py (+47/-35) hooks/percona_utils.py (+8/-6) unit_tests/test_mysql.py (+30/-18) |
To merge this branch: | bzr merge lp:~hopem/charms/trusty/percona-cluster/fix-1389670 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Liam Young (community) | Approve | ||
Review via email: mp+247596@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
- 45. By Edward Hope-Morley
-
more log cleanup
- 46. By Edward Hope-Morley
-
fixed no hostname case and updated unit test
Revision history for this message
Billy Olsen (billy-olsen) : | # |
- 47. By Edward Hope-Morley
-
cleanup
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'hooks/mysql.py' |
2 | --- hooks/mysql.py 2014-11-24 12:12:15 +0000 |
3 | +++ hooks/mysql.py 2015-01-28 18:54:36 +0000 |
4 | @@ -11,11 +11,11 @@ |
5 | from charmhelpers.core.host import pwgen, mkdir, write_file |
6 | from charmhelpers.core.hookenv import ( |
7 | relation_get, |
8 | - relation_ids, |
9 | related_units, |
10 | service_name, |
11 | unit_get, |
12 | log, |
13 | + DEBUG, |
14 | INFO, |
15 | ) |
16 | from charmhelpers.core.hookenv import config as config_get |
17 | @@ -331,36 +331,38 @@ |
18 | return mysql_config |
19 | |
20 | |
21 | -def get_allowed_units(database, username): |
22 | +def get_allowed_units(database, username, relation_id=None): |
23 | m_helper = MySQLHelper() |
24 | m_helper.connect(password=get_mysql_root_password()) |
25 | allowed_units = set() |
26 | - for relid in relation_ids('shared-db'): |
27 | - for unit in related_units(relid): |
28 | - hosts = relation_get(attribute="%s_%s" % (database, 'hostname'), |
29 | - unit=unit, rid=relid) |
30 | - if not hosts: |
31 | - hosts = [relation_get(attribute='private-address', unit=unit, |
32 | - rid=relid)] |
33 | - else: |
34 | - # hostname can be json-encoded list of hostnames |
35 | - try: |
36 | - _hosts = json.loads(hosts) |
37 | - except ValueError: |
38 | - pass |
39 | + for unit in related_units(relation_id): |
40 | + settings = relation_get(rid=relation_id, unit=unit) |
41 | + # First check for setting with prefix, then without |
42 | + for attr in ["%s_hostname" % (database), 'hostname']: |
43 | + hosts = settings.get(attr, None) |
44 | + if hosts: |
45 | + break |
46 | + |
47 | + if hosts: |
48 | + # hostname can be json-encoded list of hostnames |
49 | + try: |
50 | + hosts = json.loads(hosts) |
51 | + except ValueError: |
52 | + hosts = [hosts] |
53 | + else: |
54 | + hosts = [settings['private-address']] |
55 | + |
56 | + if hosts: |
57 | + for host in hosts: |
58 | + if m_helper.grant_exists(database, username, host): |
59 | + log("Grant exists for host '%s' on db '%s'" % |
60 | + (host, database), level=DEBUG) |
61 | + if unit not in allowed_units: |
62 | + allowed_units.add(unit) |
63 | else: |
64 | - hosts = _hosts |
65 | - |
66 | - if not isinstance(hosts, list): |
67 | - hosts = [hosts] |
68 | - |
69 | - if hosts: |
70 | - for host in hosts: |
71 | - log("Checking host '%s' grant" % (host), level=INFO) |
72 | - if m_helper.grant_exists(database, username, host): |
73 | - if unit not in allowed_units: |
74 | - allowed_units.add(unit) |
75 | - else: |
76 | - log("No hosts found for grant check", level=INFO) |
77 | + log("Grant does NOT exist for host '%s' on db '%s'" % |
78 | + (host, database), level=DEBUG) |
79 | + else: |
80 | + log("No hosts found for grant check", level=INFO) |
81 | |
82 | return allowed_units |
83 | |
84 | === modified file 'hooks/percona_hooks.py' |
85 | --- hooks/percona_hooks.py 2014-12-17 18:59:55 +0000 |
86 | +++ hooks/percona_hooks.py 2015-01-28 18:54:36 +0000 |
87 | @@ -18,12 +18,12 @@ |
88 | config, |
89 | remote_unit, |
90 | relation_type, |
91 | + DEBUG, |
92 | INFO, |
93 | ) |
94 | from charmhelpers.core.host import ( |
95 | service_restart, |
96 | file_hash, |
97 | - write_file, |
98 | lsb_release, |
99 | ) |
100 | from charmhelpers.core.templating import render |
101 | @@ -231,6 +231,23 @@ |
102 | return unit_get('private-address') |
103 | |
104 | |
105 | +def configure_db_for_hosts(hosts, database, username): |
106 | + """Hosts may be a json-encoded list of hosts or a single hostname.""" |
107 | + try: |
108 | + hosts = json.loads(hosts) |
109 | + log("Multiple hostnames provided by relation: %s" % (', '.join(hosts)), |
110 | + level=DEBUG) |
111 | + except ValueError: |
112 | + log("Single hostname provided by relation: %s" % (hosts), |
113 | + level=DEBUG) |
114 | + hosts = [hosts] |
115 | + |
116 | + for host in hosts: |
117 | + password = configure_db(host, database, username) |
118 | + |
119 | + return password |
120 | + |
121 | + |
122 | # TODO: This could be a hook common between mysql and percona-cluster |
123 | @hooks.hook('shared-db-relation-changed') |
124 | def shared_db_changed(relation_id=None, unit=None): |
125 | @@ -270,25 +287,18 @@ |
126 | database = settings['database'] |
127 | username = settings['username'] |
128 | |
129 | - # Hostname can be json-encoded list of hostnames |
130 | - try: |
131 | - hostname = json.loads(hostname) |
132 | - except ValueError: |
133 | - pass |
134 | - |
135 | - if isinstance(hostname, list): |
136 | - for host in hostname: |
137 | - password = configure_db(host, database, username) |
138 | - else: |
139 | - password = configure_db(hostname, database, username) |
140 | - |
141 | - allowed_units = unit_sorted(get_allowed_units(database, username)) |
142 | + # NOTE: do this before querying access grants |
143 | + password = configure_db_for_hosts(hostname, database, username) |
144 | + |
145 | + allowed_units = unit_sorted(get_allowed_units(database, username, |
146 | + relation_id=relation_id)) |
147 | allowed_units = ' '.join(allowed_units) |
148 | + relation_set(relation_id=relation_id, allowed_units=allowed_units) |
149 | + |
150 | db_host = get_db_host(hostname) |
151 | peer_store_and_set(relation_id=relation_id, |
152 | db_host=db_host, |
153 | - password=password, |
154 | - allowed_units=allowed_units) |
155 | + password=password) |
156 | else: |
157 | # Process multiple database setup requests. |
158 | # from incoming relation data: |
159 | @@ -316,34 +326,36 @@ |
160 | databases[db] = {} |
161 | databases[db][x] = v |
162 | |
163 | + allowed_units = {} |
164 | return_data = {} |
165 | for db in databases: |
166 | if singleset.issubset(databases[db]): |
167 | database = databases[db]['database'] |
168 | hostname = databases[db]['hostname'] |
169 | username = databases[db]['username'] |
170 | - try: |
171 | - hostname = json.loads(hostname) |
172 | - except ValueError: |
173 | - pass |
174 | - |
175 | - if isinstance(hostname, list): |
176 | - for host in hostname: |
177 | - password = configure_db(host, database, username) |
178 | - else: |
179 | - password = configure_db(hostname, database, username) |
180 | - |
181 | - return_data['_'.join([db, 'password'])] = password |
182 | - return_data['_'.join([db, 'allowed_units'])] = \ |
183 | - " ".join(unit_sorted(get_allowed_units(database, |
184 | - username))) |
185 | + |
186 | + # NOTE: do this before querying access grants |
187 | + password = configure_db_for_hosts(hostname, database, username) |
188 | + |
189 | + a_units = get_allowed_units(database, username, |
190 | + relation_id=relation_id) |
191 | + a_units = ' '.join(unit_sorted(a_units)) |
192 | + allowed_units['%s_allowed_units' % (db)] = a_units |
193 | + |
194 | + return_data['%s_password' % (db)] = password |
195 | db_host = get_db_host(hostname) |
196 | |
197 | - if len(return_data) > 0: |
198 | - peer_store_and_set(relation_id=relation_id, |
199 | + if allowed_units: |
200 | + relation_set(relation_id=relation_id, **allowed_units) |
201 | + else: |
202 | + log("No allowed_units - not setting relation settings", |
203 | + level=DEBUG) |
204 | + |
205 | + if return_data: |
206 | + peer_store_and_set(relation_id=relation_id, db_host=db_host, |
207 | **return_data) |
208 | - peer_store_and_set(relation_id=relation_id, |
209 | - db_host=db_host) |
210 | + else: |
211 | + log("No return data - not setting relation settings", level=DEBUG) |
212 | |
213 | peer_store_and_set(relation_id=relation_id, |
214 | relation_settings={'access-network': access_network}) |
215 | |
216 | === modified file 'hooks/percona_utils.py' |
217 | --- hooks/percona_utils.py 2014-12-17 21:03:54 +0000 |
218 | +++ hooks/percona_utils.py 2015-01-28 18:54:36 +0000 |
219 | @@ -16,7 +16,7 @@ |
220 | local_unit, |
221 | config, |
222 | log, |
223 | - INFO |
224 | + DEBUG, |
225 | ) |
226 | from charmhelpers.fetch import ( |
227 | apt_install, |
228 | @@ -104,11 +104,12 @@ |
229 | if not hostname or hostname in hosts: |
230 | log("(unit=%s) Ignoring hostname '%s' provided by cluster " |
231 | "relation for addr %s" % |
232 | - (unit, hostname, private_address)) |
233 | + (unit, hostname, private_address), level=DEBUG) |
234 | continue |
235 | else: |
236 | log("(unit=%s) hostname '%s' provided by cluster relation " |
237 | - "for addr %s" % (unit, hostname, private_address)) |
238 | + "for addr %s" % (unit, hostname, private_address), |
239 | + level=DEBUG) |
240 | |
241 | hosts_map[private_address] = hostname |
242 | hosts.append(hostname) |
243 | @@ -175,8 +176,8 @@ |
244 | with open(HOSTS_FILE, 'r') as hosts: |
245 | lines = hosts.readlines() |
246 | |
247 | - log("Updating hosts file with: %s (current: %s)" % (map, lines), |
248 | - level=INFO) |
249 | + log("Updating %s with: %s (current: %s)" % (HOSTS_FILE, map, lines), |
250 | + level=DEBUG) |
251 | |
252 | newlines = [] |
253 | for ip, hostname in map.items(): |
254 | @@ -189,7 +190,8 @@ |
255 | if len(line) < 2 or not (_line[0] == ip or hostname in _line[1:]): |
256 | keepers.append(line) |
257 | else: |
258 | - log("Removing line '%s' from hosts file" % (line)) |
259 | + log("Marking line '%s' for update or removal" % (line.strip()), |
260 | + level=DEBUG) |
261 | |
262 | lines = keepers |
263 | newlines.append("%s %s\n" % (ip, hostname)) |
264 | |
265 | === modified file 'unit_tests/test_mysql.py' |
266 | --- unit_tests/test_mysql.py 2014-10-15 16:09:41 +0000 |
267 | +++ unit_tests/test_mysql.py 2015-01-28 18:54:36 +0000 |
268 | @@ -15,27 +15,39 @@ |
269 | @mock.patch('mysql.MySQLHelper', autospec=True) |
270 | @mock.patch('mysql.relation_get') |
271 | @mock.patch('mysql.related_units') |
272 | - @mock.patch('mysql.relation_ids') |
273 | @mock.patch('mysql.log') |
274 | - def test_get_allowed_units(self, mock_log, mock_relation_ids, |
275 | - mock_related_units, |
276 | + def test_get_allowed_units(self, mock_log, mock_related_units, |
277 | mock_relation_get, mock_helper, |
278 | mock_get_password): |
279 | - mock_relation_ids.return_value = ['r1'] |
280 | - mock_related_units.return_value = ['ru1', 'ru2'] |
281 | - |
282 | - def mock_rel_get(attribute, unit, rid): |
283 | - if unit == 'ru2': |
284 | - d = {'private-address': '1.2.3.4', |
285 | - 'dbA_hostname': json.dumps(['2.3.4.5', '6.7.8.9'])} |
286 | - else: |
287 | - d = {'private-address': '1.2.3.4'} |
288 | - |
289 | - return d.get(attribute, None) |
290 | + |
291 | + def mock_rel_get(unit, rid): |
292 | + if unit == 'unit/0': |
293 | + # Non-prefixed settings |
294 | + d = {'private-address': '10.0.0.1', |
295 | + 'hostname': 'hostA'} |
296 | + elif unit == 'unit/1': |
297 | + # Containing prefixed settings |
298 | + d = {'private-address': '10.0.0.2', |
299 | + 'dbA_hostname': json.dumps(['10.0.0.2', '2001:db8:1::2'])} |
300 | + elif unit == 'unit/2': |
301 | + # No hostname |
302 | + d = {'private-address': '10.0.0.3'} |
303 | + |
304 | + return d |
305 | |
306 | mock_relation_get.side_effect = mock_rel_get |
307 | + mock_related_units.return_value = ['unit/0', 'unit/1', 'unit/2'] |
308 | + |
309 | units = mysql.get_allowed_units('dbA', 'userA') |
310 | - mock_helper.return_value.grant_exists.assert_called_with('dbA', |
311 | - 'userA', |
312 | - '6.7.8.9') |
313 | - self.assertEqual(units, set(['ru1', 'ru2'])) |
314 | + |
315 | + calls = [mock.call('dbA', 'userA', 'hostA'), |
316 | + mock.call().__nonzero__(), |
317 | + mock.call('dbA', 'userA', '10.0.0.2'), |
318 | + mock.call().__nonzero__(), |
319 | + mock.call('dbA', 'userA', '2001:db8:1::2'), |
320 | + mock.call().__nonzero__(), |
321 | + mock.call('dbA', 'userA', '10.0.0.3'), |
322 | + mock.call().__nonzero__()] |
323 | + |
324 | + mock_helper.return_value.grant_exists.assert_has_calls(calls) |
325 | + self.assertEqual(units, set(['unit/0', 'unit/1', 'unit/2'])) |
Approve