From 627dd3073c69d128a8b4b1b62180d8d8ea6dc790 Mon Sep 17 00:00:00 2001 From: rafcio19 Date: Sat, 17 Jun 2023 12:19:59 +0100 Subject: [PATCH] IAM: additional role on instance profile validation (#6415) --- moto/iam/models.py | 7 +++- tests/test_iam/test_iam.py | 77 ++++++++++++++++++++++++-------------- 2 files changed, 54 insertions(+), 30 deletions(-) diff --git a/moto/iam/models.py b/moto/iam/models.py index c1d666d0c..a41c76214 100644 --- a/moto/iam/models.py +++ b/moto/iam/models.py @@ -2375,7 +2375,12 @@ class IAMBackend(BaseBackend): def add_role_to_instance_profile(self, profile_name: str, role_name: str) -> None: profile = self.get_instance_profile(profile_name) role = self.get_role(role_name) - profile.roles.append(role) + if not profile.roles: + profile.roles.append(role) + else: + raise IAMLimitExceededException( + "Cannot exceed quota for InstanceSessionsPerInstanceProfile: 1" + ) def remove_role_from_instance_profile( self, profile_name: str, role_name: str diff --git a/tests/test_iam/test_iam.py b/tests/test_iam/test_iam.py index bbc8f6ac3..a73c40064 100644 --- a/tests/test_iam/test_iam.py +++ b/tests/test_iam/test_iam.py @@ -69,6 +69,23 @@ MOCK_POLICY_3 = """ } """ +MOCK_STS_EC2_POLICY_DOCUMENT = """{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Service": [ + "ec2.amazonaws.com" + ] + }, + "Action": [ + "sts:AssumeRole" + ] + } + ] + }""" + @mock_iam def test_get_role__should_throw__when_role_does_not_exist(): @@ -153,6 +170,35 @@ def test_create_instance_profile_should_throw_when_name_is_not_unique(): conn.create_instance_profile(InstanceProfileName="unique-instance-profile") +@mock_iam +def test_create_add_additional_roles_to_instance_profile_error(): + + # Setup + iam = boto3.client("iam", region_name="us-east-1") + name = "test_profile" + role_name = "test_role" + role_name2 = "test_role2" + iam.create_instance_profile(InstanceProfileName=name) + iam.create_role( + RoleName=role_name, AssumeRolePolicyDocument=MOCK_STS_EC2_POLICY_DOCUMENT + ) + iam.create_role( + RoleName=role_name2, AssumeRolePolicyDocument=MOCK_STS_EC2_POLICY_DOCUMENT + ) + iam.add_role_to_instance_profile(InstanceProfileName=name, RoleName=role_name) + + # Execute + with pytest.raises(ClientError) as exc: + iam.add_role_to_instance_profile(InstanceProfileName=name, RoleName=role_name2) + + # Verify + err = exc.value.response["Error"] + assert err["Code"].should.equal("LimitExceeded") + assert err["Message"].should.equal( + "Cannot exceed quota for InstanceSessionsPerInstanceProfile: 1" + ) + + @mock_iam def test_remove_role_from_instance_profile(): conn = boto3.client("iam", region_name="us-east-1") @@ -420,20 +466,7 @@ def test_update_assume_role_valid_policy(): conn.create_role( RoleName="my-role", AssumeRolePolicyDocument="some policy", Path="my-path" ) - policy_document = """ - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Principal": { - "Service": ["ec2.amazonaws.com"] - }, - "Action": ["sts:AssumeRole"] - } - ] - } -""" + policy_document = MOCK_STS_EC2_POLICY_DOCUMENT conn.update_assume_role_policy(RoleName="my-role", PolicyDocument=policy_document) role = conn.get_role(RoleName="my-role")["Role"] role["AssumeRolePolicyDocument"]["Statement"][0]["Action"][0].should.equal( @@ -3381,21 +3414,7 @@ def test_list_user_tags(): def test_delete_role_with_instance_profiles_present(): iam = boto3.client("iam", region_name="us-east-1") - trust_policy = """ - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Principal": { - "Service": "ec2.amazonaws.com" - }, - "Action": "sts:AssumeRole" - } - ] - } - """ - trust_policy = trust_policy.strip() + trust_policy = MOCK_STS_EC2_POLICY_DOCUMENT.strip() iam.create_role(RoleName="Role1", AssumeRolePolicyDocument=trust_policy) iam.create_instance_profile(InstanceProfileName="IP1")