Skip to content
This repository was archived by the owner on Jan 1, 2024. It is now read-only.

Commit 89daacd

Browse files
authored
Handle bad membership members (#343)
Before this patch getting control instance failed on checking membership members if some member payload is empty. It caused because an empty Lua table is serialized as an empty array, but the Python module expects a dict. Since this patch, all empty table cases are handled for membership.
1 parent f064909 commit 89daacd

File tree

5 files changed

+57
-4
lines changed

5 files changed

+57
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ README.md to use the newest tag with new release
1515
- Fail on getting control instance when all unjoined instances haven't
1616
`replicaset_alias` set
1717
- Support of Ansible 4.0
18+
- Handling of bad membership members - empty or with empty payload
1819

1920
### Added
2021

library/cartridge_get_control_instance.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ def candidate_is_ok(uri, names_by_uris, module_hostvars):
9393
def get_control_instance_name(module_hostvars, play_hosts, control_console):
9494
members = get_membership_members(control_console)
9595

96+
if not members:
97+
return None, "Membership is empty"
98+
9699
# try to find joined alive instance that isn't set to be expelled
97100
alive_instances_uris = set()
98101
joined_instances_uris = set()
@@ -102,10 +105,16 @@ def get_control_instance_name(module_hostvars, play_hosts, control_console):
102105
names_by_uris = {}
103106

104107
for uri, member in sorted(members.items()):
108+
if not member:
109+
return None, "Membership contains empty member with URI %s" % uri
110+
105111
member_payload = member.get('payload')
106112
if member_payload is None:
107113
return None, "Instance with URI %s doesn't contain payload" % uri
108114

115+
if not member_payload:
116+
return None, "Instance with URI %s has empty payload" % uri
117+
109118
instance_name = member_payload.get('alias')
110119
if instance_name is None:
111120
return None, "Instance with URI %s payload doesn't contain alias" % uri

unit/instance.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,11 @@ def set_membership_members(self, specified_members, with_payload=True):
278278

279279
for m in specified_members:
280280
uri = m['uri']
281+
282+
if m.get('empty'):
283+
members[uri] = {}
284+
continue
285+
281286
member = {
282287
'uri': uri,
283288
'status': m.get('status', 'alive'),
@@ -293,6 +298,9 @@ def set_membership_members(self, specified_members, with_payload=True):
293298
}
294299
})
295300

301+
if m.get('empty_payload'):
302+
member.update({"payload": {}})
303+
296304
members[uri] = member
297305

298306
self.set_variable('membership_members', members)

unit/test_get_control_instance.py

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,38 @@ def setUp(self):
5959

6060
self.instance.start()
6161

62-
def test_instance_without_alias(self):
62+
def test_bad_members(self):
6363
hostvars = get_instance_hostvars('instance-1')
64+
hostvars.update(get_instance_hostvars('empty-member'))
65+
hostvars.update(get_instance_hostvars('empty-payload'))
6466

65-
# with UUID (already bootstrapped) and without alias
67+
# empty membership
68+
self.instance.set_membership_members([])
69+
res = call_get_control_instance('myapp', self.console_sock, hostvars)
70+
self.assertTrue(res.failed)
71+
self.assertIn("Membership is empty", res.msg)
72+
73+
# empty member
74+
self.instance.set_membership_members([
75+
utils.get_member('empty-member', empty=True),
76+
utils.get_member('instance-1'),
77+
])
78+
res = call_get_control_instance('myapp', self.console_sock, hostvars)
79+
self.assertTrue(res.failed)
80+
self.assertIn("Membership contains empty member with URI empty-member-uri", res.msg)
81+
82+
# with empty payload
83+
self.instance.set_membership_members([
84+
utils.get_member('empty-payload', empty_payload=True),
85+
utils.get_member('instance-1'),
86+
])
87+
res = call_get_control_instance('myapp', self.console_sock, hostvars)
88+
self.assertTrue(res.failed)
89+
self.assertIn("Instance with URI empty-payload-uri has empty payload", res.msg)
90+
91+
# without alias
6692
self.instance.set_membership_members([
67-
utils.get_member('instance-1', with_uuid=True, with_alias=False),
93+
utils.get_member('instance-1', with_alias=False),
6894
])
6995
res = call_get_control_instance('myapp', self.console_sock, hostvars)
7096
self.assertTrue(res.failed)

unit/utils.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
1-
def get_member(alias, with_alias=True, uuid=None, with_uuid=False, status=None, state=None):
1+
def get_member(alias, with_alias=True, empty=False, empty_payload=False,
2+
uuid=None, with_uuid=False, status=None, state=None):
23
member = {'uri': '%s-uri' % alias}
34

5+
if empty:
6+
member.update({'empty': True})
7+
return member
8+
9+
if empty_payload:
10+
member.update({'empty_payload': True})
11+
return member
12+
413
if with_alias:
514
member.update({'alias': alias})
615

0 commit comments

Comments
 (0)