Skip to content

Commit

Permalink
IAM: add instance profile tagging (#7665)
Browse files Browse the repository at this point in the history
  • Loading branch information
SoenkeD committed May 11, 2024
1 parent 40d78ff commit 408126a
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 4 deletions.
4 changes: 2 additions & 2 deletions IMPLEMENTATION_COVERAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4084,15 +4084,15 @@
- [ ] set_security_token_service_preferences
- [ ] simulate_custom_policy
- [ ] simulate_principal_policy
- [ ] tag_instance_profile
- [X] tag_instance_profile
- [ ] tag_mfa_device
- [X] tag_open_id_connect_provider
- [X] tag_policy
- [X] tag_role
- [ ] tag_saml_provider
- [ ] tag_server_certificate
- [X] tag_user
- [ ] untag_instance_profile
- [X] untag_instance_profile
- [ ] untag_mfa_device
- [X] untag_open_id_connect_provider
- [X] untag_policy
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/services/iam.rst
Original file line number Diff line number Diff line change
Expand Up @@ -164,15 +164,15 @@ iam
- [ ] set_security_token_service_preferences
- [ ] simulate_custom_policy
- [ ] simulate_principal_policy
- [ ] tag_instance_profile
- [X] tag_instance_profile
- [ ] tag_mfa_device
- [X] tag_open_id_connect_provider
- [X] tag_policy
- [X] tag_role
- [ ] tag_saml_provider
- [ ] tag_server_certificate
- [X] tag_user
- [ ] untag_instance_profile
- [X] untag_instance_profile
- [ ] untag_mfa_device
- [X] untag_open_id_connect_provider
- [X] untag_policy
Expand Down
16 changes: 16 additions & 0 deletions moto/iam/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3320,6 +3320,22 @@ def get_service_linked_role_deletion_status(self) -> bool:
"""
return True

def tag_instance_profile(
self, instance_profile_name: str, tags: List[Dict[str, str]] = []
) -> None:
profile = self.get_instance_profile(profile_name=instance_profile_name)

for value in tags:
profile.tags[value["Key"]] = value["Value"]

def untag_instance_profile(
self, instance_profile_name: str, tagKeys: List[str] = []
) -> None:
profile = self.get_instance_profile(profile_name=instance_profile_name)

for value in tagKeys:
del profile.tags[value]


iam_backends = BackendDict(
IAMBackend, "iam", use_boto3_regions=False, additional_regions=["global"]
Expand Down
36 changes: 36 additions & 0 deletions moto/iam/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -1128,6 +1128,28 @@ def get_service_linked_role_deletion_status(self) -> str:
)
return template.render()

def tag_instance_profile(self) -> str:
instance_profile_name = self._get_param("InstanceProfileName")
tags = self._get_multi_param("Tags.member")

self.backend.tag_instance_profile(
instance_profile_name=instance_profile_name,
tags=tags,
)
template = self.response_template(TAG_INSTANCE_PROFILE_TEMPLATE)
return template.render()

def untag_instance_profile(self) -> str:
instance_profile_name = self._get_param("InstanceProfileName")
tags = self._get_multi_param("TagKeys.member")

self.backend.untag_instance_profile(
instance_profile_name=instance_profile_name,
tagKeys=tags,
)
template = self.response_template(UNTAG_INSTANCE_PROFILE_TEMPLATE)
return template.render()


LIST_ENTITIES_FOR_POLICY_TEMPLATE = """<ListEntitiesForPolicyResponse>
<ListEntitiesForPolicyResult>
Expand Down Expand Up @@ -2774,3 +2796,17 @@ def get_service_linked_role_deletion_status(self) -> str:
<RequestId>EXAMPLE8-90ab-cdef-fedc-ba987EXAMPLE</RequestId>
</ResponseMetadata>
</UntagUserResponse>"""

TAG_INSTANCE_PROFILE_TEMPLATE = """<TagInstanceProfileResponse xmlns="https://iam.amazonaws.com/doc/2010-05-08/">
<ResponseMetadata>
<RequestId>EXAMPLE8-90ab-cdef-fedc-ba987EXAMPLE</RequestId>
</ResponseMetadata>
</TagInstanceProfileResponse>
"""

UNTAG_INSTANCE_PROFILE_TEMPLATE = """<UntagInstanceProfileResponse xmlns="https://iam.amazonaws.com/doc/2010-05-08/">
<ResponseMetadata>
<RequestId>EXAMPLE8-90ab-cdef-fedc-ba987EXAMPLE</RequestId>
</ResponseMetadata>
</UntagInstanceProfileResponse>
"""
36 changes: 36 additions & 0 deletions tests/test_iam/test_iam.py
Original file line number Diff line number Diff line change
Expand Up @@ -4803,3 +4803,39 @@ def test_delete_service_linked_role():
err = ex.value.response["Error"]
assert err["Code"] == "NoSuchEntity"
assert "not found" in err["Message"]


@mock_aws
def test_tag_instance_profile():
client = boto3.client("iam", region_name="eu-central-1")

name = "test-ip"
tags = [{"Key": "MyKey", "Value": "myValue"}]

client.create_instance_profile(InstanceProfileName=name)
client.tag_instance_profile(InstanceProfileName=name, Tags=tags)
ip = client.get_instance_profile(InstanceProfileName=name)

assert ip["InstanceProfile"]["Tags"] == tags

# add another tag
addTags = [{"Key": "MyKey2", "Value": "myValue2"}]
client.tag_instance_profile(InstanceProfileName=name, Tags=addTags)
ip = client.get_instance_profile(InstanceProfileName=name)

assert ip["InstanceProfile"]["Tags"] == tags + addTags


@mock_aws
def test_untag_instance_profile():
client = boto3.client("iam", region_name="eu-central-1")

name = "test-ip"
tags = [{"Key": "MyKey", "Value": "myValue"}]
unTags = ["MyKey"]

client.create_instance_profile(InstanceProfileName=name, Tags=tags)
client.untag_instance_profile(InstanceProfileName=name, TagKeys=unTags)
ip = client.get_instance_profile(InstanceProfileName=name)

assert ip["InstanceProfile"]["Tags"] == []

0 comments on commit 408126a

Please sign in to comment.