diff --git a/control_panel_api/aws.py b/control_panel_api/aws.py index b4ac0bc51..1f0e007c5 100644 --- a/control_panel_api/aws.py +++ b/control_panel_api/aws.py @@ -94,6 +94,7 @@ def delete_role(self, role_name): """Delete the given IAM role.""" self._detach_role_policies(role_name) + self._delete_role_inline_policies(role_name) self._do('iam', 'delete_role', RoleName=role_name) def _detach_role_policies(self, role_name): @@ -106,9 +107,27 @@ def _detach_role_policies(self, role_name): for policy in policies["AttachedPolicies"]: self.detach_policy_from_role( role_name=role_name, - policy_arn=policy["PolicyArn"] + policy_arn=policy["PolicyArn"], ) + def _delete_role_inline_policies(self, role_name): + """Deletes all inline policies in the given role""" + + policies = self._do( + 'iam', 'list_role_policies', RoleName=role_name) + + if policies: + for policy_name in policies["PolicyNames"]: + self.delete_role_inline_policy( + role_name=role_name, + policy_name=policy_name, + ) + + def delete_role_inline_policy(self, policy_name, role_name): + self._do('iam', 'delete_role_policy', + RoleName=role_name, + PolicyName=policy_name) + def attach_policy_to_role(self, policy_arn, role_name): self._do('iam', 'attach_role_policy', RoleName=role_name, diff --git a/control_panel_api/tests/test_aws.py b/control_panel_api/tests/test_aws.py index 5a25b294f..abba8deb5 100644 --- a/control_panel_api/tests/test_aws.py +++ b/control_panel_api/tests/test_aws.py @@ -65,8 +65,18 @@ def test_attach_policy_to_role(self): ) def test_detach_policy_from_role(self): - aws.detach_policy_from_role('policyarn', 'foo') - aws.client.return_value.detach_role_policy.assert_called() + aws.detach_policy_from_role('policy_arn', 'role_name') + aws.client.return_value.detach_role_policy.assert_called_with( + RoleName='role_name', + PolicyArn='policy_arn', + ) + + def test_delete_role_inline_policy(self): + aws.delete_role_inline_policy('policy_name', 'role_name') + aws.client.return_value.delete_role_policy.assert_called_with( + RoleName='role_name', + PolicyName='policy_name', + ) def test_create_role(self): role_name = "a_role" @@ -80,25 +90,39 @@ def test_create_role(self): ) def test_delete_role(self): - aws.client.return_value.list_attached_role_policies.return_value = { + aws_client = aws.client.return_value + aws_client.list_attached_role_policies.return_value = { "AttachedPolicies": [ {"PolicyArn": "arn_1"}, {"PolicyArn": "arn_2"}, ], } + aws_client.list_role_policies.return_value = { + "PolicyNames": [ + 's3-access', + 'other-inline-policy', + ], + } role_name = "a_role" aws.delete_role(role_name) + # Check managed policies are detached from role expected_detach_calls = [ call(RoleName=role_name, PolicyArn='arn_1'), call(RoleName=role_name, PolicyArn='arn_2'), ] - - # Check policies are detached from role - aws.client.return_value.detach_role_policy.assert_has_calls( + aws_client.detach_role_policy.assert_has_calls( expected_detach_calls) + # Check inline policies are deleted + expected_delete_policy_calls = [ + call(RoleName=role_name, PolicyName='s3-access'), + call(RoleName=role_name, PolicyName='other-inline-policy'), + ] + aws_client.delete_role_policy.assert_has_calls( + expected_delete_policy_calls) + # Check role is deleted aws.client.return_value.delete_role.assert_called_with( RoleName=role_name,