Skip to content

Commit 3f75c59

Browse files
authored
Fix bug in updating spec.inlinePolicies (#81)
The bug occurs when updating an existing item in `spec.inlinePolicies`. The code incorrectly includes both the old(to remove) and new(to add)values when using `lo.Difference`. This causes the code to first attempt to replace the xisting policies with a call to `iam::PutRolePolicy` and then mistakenly "delete" them right after. This patch fixes this bug by calling `lo.Find` to double check whether we need to keep an inline policy (if it only needs to be updated) By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent 0e0658d commit 3f75c59

File tree

2 files changed

+54
-3
lines changed

2 files changed

+54
-3
lines changed

pkg/resource/role/hooks.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,13 @@ func (rm *resourceManager) syncInlinePolicies(
226226
return err
227227
}
228228
}
229+
229230
for _, pair := range toDelete {
231+
// do not remove elements we just updated with `addInlinePolicy`
232+
if _, ok := lo.Find(toAdd, func(entry lo.Entry[string, string]) bool { return entry.Key == pair.Key }); ok {
233+
continue
234+
}
235+
230236
polName := pair.Key
231237
rlog.Debug(
232238
"removing inline policy from role",
@@ -236,7 +242,6 @@ func (rm *resourceManager) syncInlinePolicies(
236242
return err
237243
}
238244
}
239-
240245
return nil
241246
}
242247

test/e2e/tests/test_role.py

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,20 @@ def test_crud(self, simple_role):
176176
"Action": ["ec2:Get*"],
177177
"Resource": ["*"]
178178
}]
179+
}'''
180+
inline_doc_2 = '''{
181+
"Version": "2012-10-17",
182+
"Statement": [{
183+
"Effect": "Allow",
184+
"Action": ["s3:Get*"],
185+
"Resource": ["*"]
186+
}]
179187
}'''
180188
updates = {
181189
"spec": {
182190
"inlinePolicies": {
183191
"ec2get": inline_doc,
192+
"s3get": inline_doc_2,
184193
},
185194
},
186195
}
@@ -189,21 +198,58 @@ def test_crud(self, simple_role):
189198

190199
expect_inline_policies = {
191200
'ec2get': inline_doc,
201+
's3get': inline_doc_2,
192202
}
193203
cr = k8s.get_resource(ref)
194204
assert cr is not None
195205
assert 'spec' in cr
196206
assert 'inlinePolicies' in cr['spec']
197-
assert len(cr['spec']['inlinePolicies']) == 1
207+
assert len(cr['spec']['inlinePolicies']) == 2
198208
assert expect_inline_policies == cr['spec']['inlinePolicies']
199209

200210
latest_inline_policies = role.get_inline_policies(role_name)
201-
assert len(latest_inline_policies) == 1
211+
assert len(latest_inline_policies) == 2
202212
assert 'ec2get' in latest_inline_policies
213+
203214
got_pol_doc = latest_inline_policies['ec2get']
204215
nospace_got_doc = "".join(c for c in got_pol_doc if not c.isspace())
205216
nospace_exp_doc = "".join(c for c in inline_doc if not c.isspace())
217+
assert nospace_exp_doc == nospace_got_doc
206218

219+
got_pol_doc = latest_inline_policies['s3get']
220+
nospace_got_doc = "".join(c for c in got_pol_doc if not c.isspace())
221+
nospace_exp_doc = "".join(c for c in inline_doc_2 if not c.isspace())
222+
assert nospace_exp_doc == nospace_got_doc
223+
224+
inline_doc_s3_get_object = '''{
225+
"Version": "2012-10-17",
226+
"Statement": [{
227+
"Effect": "Allow",
228+
"Action": ["s3:GetObject"],
229+
"Resource": ["*"]
230+
}]
231+
}'''
232+
# update s3get policy document
233+
updates = {
234+
"spec": {
235+
"inlinePolicies": {
236+
"ec2get": inline_doc,
237+
"s3get": inline_doc_s3_get_object,
238+
},
239+
},
240+
}
241+
k8s.patch_custom_resource(ref, updates)
242+
time.sleep(MODIFY_WAIT_AFTER_SECONDS)
243+
244+
latest_inline_policies = role.get_inline_policies(role_name)
245+
assert len(latest_inline_policies) == 2
246+
assert 's3get' in latest_inline_policies
247+
assert 'ec2get' in latest_inline_policies
248+
249+
# expect s3get policy document to change into inlinde_doc_s3_get_object
250+
got_pol_doc = latest_inline_policies['s3get']
251+
nospace_got_doc = "".join(c for c in got_pol_doc if not c.isspace())
252+
nospace_exp_doc = "".join(c for c in inline_doc_s3_get_object if not c.isspace())
207253
assert nospace_exp_doc == nospace_got_doc
208254

209255
# Remove the inline policy we just added and check the updates are

0 commit comments

Comments
 (0)