From c10afa3ab506d82cd56e2723b78c829ff416888f Mon Sep 17 00:00:00 2001 From: gruebel Date: Sun, 17 Nov 2019 15:10:38 +0100 Subject: [PATCH] Add organizations.list_tags_for_resource --- IMPLEMENTATION_COVERAGE.md | 2 +- moto/organizations/models.py | 12 ++++++ moto/organizations/responses.py | 5 +++ .../test_organizations_boto3.py | 41 +++++++++++++++++++ 4 files changed, 59 insertions(+), 1 deletion(-) diff --git a/IMPLEMENTATION_COVERAGE.md b/IMPLEMENTATION_COVERAGE.md index d6a4d8174..213775d83 100644 --- a/IMPLEMENTATION_COVERAGE.md +++ b/IMPLEMENTATION_COVERAGE.md @@ -4762,7 +4762,7 @@ - [X] list_policies - [X] list_policies_for_target - [X] list_roots -- [ ] list_tags_for_resource +- [x] list_tags_for_resource - [X] list_targets_for_policy - [X] move_account - [ ] remove_account_from_organization diff --git a/moto/organizations/models.py b/moto/organizations/models.py index 2fb0a6656..b5059fe8d 100644 --- a/moto/organizations/models.py +++ b/moto/organizations/models.py @@ -455,5 +455,17 @@ class OrganizationsBackend(BaseBackend): new_tags = {tag["Key"]: tag["Value"] for tag in kwargs["Tags"]} account.tags.update(new_tags) + def list_tags_for_resource(self, **kwargs): + account = next((a for a in self.accounts if a.id == kwargs["ResourceId"]), None) + + if account is None: + raise RESTError( + "InvalidInputException", + "You provided a value that does not match the required pattern.", + ) + + tags = [{"Key": key, "Value": value} for key, value in account.tags.items()] + return dict(Tags=tags) + organizations_backend = OrganizationsBackend() diff --git a/moto/organizations/responses.py b/moto/organizations/responses.py index 11093bae1..ab01ffb8a 100644 --- a/moto/organizations/responses.py +++ b/moto/organizations/responses.py @@ -124,3 +124,8 @@ class OrganizationsResponse(BaseResponse): return json.dumps( self.organizations_backend.tag_resource(**self.request_params) ) + + def list_tags_for_resource(self): + return json.dumps( + self.organizations_backend.list_tags_for_resource(**self.request_params) + ) diff --git a/tests/test_organizations/test_organizations_boto3.py b/tests/test_organizations/test_organizations_boto3.py index 95b115548..27989c276 100644 --- a/tests/test_organizations/test_organizations_boto3.py +++ b/tests/test_organizations/test_organizations_boto3.py @@ -618,6 +618,17 @@ def test_tag_resource(): client.tag_resource(ResourceId=account_id, Tags=[{"Key": "key", "Value": "value"}]) + response = client.list_tags_for_resource(ResourceId=account_id) + response["Tags"].should.equal([{"Key": "key", "Value": "value"}]) + + # adding a tag with an existing key, will update the value + client.tag_resource( + ResourceId=account_id, Tags=[{"Key": "key", "Value": "new-value"}] + ) + + response = client.list_tags_for_resource(ResourceId=account_id) + response["Tags"].should.equal([{"Key": "key", "Value": "new-value"}]) + @mock_organizations def test_tag_resource_errors(): @@ -635,3 +646,33 @@ def test_tag_resource_errors(): ex.response["Error"]["Message"].should.contain( "You provided a value that does not match the required pattern." ) + + +@mock_organizations +def test_list_tags_for_resource(): + client = boto3.client("organizations", region_name="us-east-1") + client.create_organization(FeatureSet="ALL") + account_id = client.create_account(AccountName=mockname, Email=mockemail)[ + "CreateAccountStatus" + ]["AccountId"] + client.tag_resource(ResourceId=account_id, Tags=[{"Key": "key", "Value": "value"}]) + + response = client.list_tags_for_resource(ResourceId=account_id) + + response["Tags"].should.equal([{"Key": "key", "Value": "value"}]) + + +@mock_organizations +def test_list_tags_for_resource_errors(): + client = boto3.client("organizations", region_name="us-east-1") + client.create_organization(FeatureSet="ALL") + + with assert_raises(ClientError) as e: + client.list_tags_for_resource(ResourceId="000000000000") + ex = e.exception + ex.operation_name.should.equal("ListTagsForResource") + ex.response["Error"]["Code"].should.equal("400") + ex.response["Error"]["Message"].should.contain("InvalidInputException") + ex.response["Error"]["Message"].should.contain( + "You provided a value that does not match the required pattern." + )