Support CloudFormation and ECS ResourceTypeFilters in ResourceGroupsTaggingAPI get_resources() (#6023)
This commit is contained in:
parent
d022b404d3
commit
1934d24ad5
@ -13,6 +13,7 @@ from moto.glacier import glacier_backends
|
|||||||
from moto.redshift import redshift_backends
|
from moto.redshift import redshift_backends
|
||||||
from moto.emr import emr_backends
|
from moto.emr import emr_backends
|
||||||
from moto.awslambda import lambda_backends
|
from moto.awslambda import lambda_backends
|
||||||
|
from moto.ecs import ecs_backends
|
||||||
|
|
||||||
# Left: EC2 ElastiCache RDS ELB CloudFront WorkSpaces Lambda EMR Glacier Kinesis Redshift Route53
|
# Left: EC2 ElastiCache RDS ELB CloudFront WorkSpaces Lambda EMR Glacier Kinesis Redshift Route53
|
||||||
# StorageGateway DynamoDB MachineLearning ACM DirectConnect DirectoryService CloudHSM
|
# StorageGateway DynamoDB MachineLearning ACM DirectConnect DirectoryService CloudHSM
|
||||||
@ -106,6 +107,13 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
|
|||||||
"""
|
"""
|
||||||
return lambda_backends[self.account_id][self.region_name]
|
return lambda_backends[self.account_id][self.region_name]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ecs_backend(self):
|
||||||
|
"""
|
||||||
|
:rtype: moto.ecs.models.EcsnBackend
|
||||||
|
"""
|
||||||
|
return ecs_backends[self.account_id][self.region_name]
|
||||||
|
|
||||||
def _get_resources_generator(self, tag_filters=None, resource_type_filters=None):
|
def _get_resources_generator(self, tag_filters=None, resource_type_filters=None):
|
||||||
# Look at
|
# Look at
|
||||||
# https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html
|
# https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html
|
||||||
@ -143,7 +151,19 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
|
|||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# Do S3, resource type s3
|
def format_tags(tags):
|
||||||
|
result = []
|
||||||
|
for key, value in tags.items():
|
||||||
|
result.append({"Key": key, "Value": value})
|
||||||
|
return result
|
||||||
|
|
||||||
|
def format_tag_keys(tags, keys):
|
||||||
|
result = []
|
||||||
|
for tag in tags:
|
||||||
|
result.append({"Key": tag[keys[0]], "Value": tag[keys[1]]})
|
||||||
|
return result
|
||||||
|
|
||||||
|
# S3
|
||||||
if not resource_type_filters or "s3" in resource_type_filters:
|
if not resource_type_filters or "s3" in resource_type_filters:
|
||||||
for bucket in self.s3_backend.buckets.values():
|
for bucket in self.s3_backend.buckets.values():
|
||||||
tags = self.s3_backend.tagger.list_tags_for_resource(bucket.arn)["Tags"]
|
tags = self.s3_backend.tagger.list_tags_for_resource(bucket.arn)["Tags"]
|
||||||
@ -153,12 +173,45 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
|
|||||||
continue
|
continue
|
||||||
yield {"ResourceARN": "arn:aws:s3:::" + bucket.name, "Tags": tags}
|
yield {"ResourceARN": "arn:aws:s3:::" + bucket.name, "Tags": tags}
|
||||||
|
|
||||||
# EC2 tags
|
# CloudFormation
|
||||||
def get_ec2_tags(res_id):
|
if not resource_type_filters or "cloudformation:stack" in resource_type_filters:
|
||||||
result = []
|
|
||||||
for key, value in self.ec2_backend.tags.get(res_id, {}).items():
|
try:
|
||||||
result.append({"Key": key, "Value": value})
|
from moto.cloudformation import cloudformation_backends
|
||||||
return result
|
|
||||||
|
backend = cloudformation_backends[self.account_id][self.region_name]
|
||||||
|
|
||||||
|
for stack in backend.stacks.values():
|
||||||
|
tags = format_tags(stack.tags)
|
||||||
|
if not tag_filter(tags):
|
||||||
|
continue
|
||||||
|
yield {"ResourceARN": f"{stack.stack_id}", "Tags": tags}
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# ECS
|
||||||
|
if not resource_type_filters or "ecs:service" in resource_type_filters:
|
||||||
|
for service in self.ecs_backend.services.values():
|
||||||
|
tags = format_tag_keys(service.tags, ["key", "value"])
|
||||||
|
if not tag_filter(tags):
|
||||||
|
continue
|
||||||
|
yield {"ResourceARN": f"{service.physical_resource_id}", "Tags": tags}
|
||||||
|
|
||||||
|
if not resource_type_filters or "ecs:cluster" in resource_type_filters:
|
||||||
|
for cluster in self.ecs_backend.clusters.values():
|
||||||
|
tags = format_tag_keys(cluster.tags, ["key", "value"])
|
||||||
|
if not tag_filter(tags):
|
||||||
|
continue
|
||||||
|
yield {"ResourceARN": f"{cluster.arn}", "Tags": tags}
|
||||||
|
|
||||||
|
if not resource_type_filters or "ecs:task" in resource_type_filters:
|
||||||
|
for task_dict in self.ecs_backend.tasks.values():
|
||||||
|
for task in task_dict.values():
|
||||||
|
tags = format_tag_keys(task.tags, ["key", "value"])
|
||||||
|
if not tag_filter(tags):
|
||||||
|
continue
|
||||||
|
yield {"ResourceARN": f"{task.task_arn}", "Tags": tags}
|
||||||
|
|
||||||
# EC2 AMI, resource type ec2:image
|
# EC2 AMI, resource type ec2:image
|
||||||
if (
|
if (
|
||||||
@ -167,7 +220,7 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
|
|||||||
or "ec2:image" in resource_type_filters
|
or "ec2:image" in resource_type_filters
|
||||||
):
|
):
|
||||||
for ami in self.ec2_backend.amis.values():
|
for ami in self.ec2_backend.amis.values():
|
||||||
tags = get_ec2_tags(ami.id)
|
tags = format_tags(self.ec2_backend.tags.get(ami.id, {}))
|
||||||
|
|
||||||
if not tags or not tag_filter(
|
if not tags or not tag_filter(
|
||||||
tags
|
tags
|
||||||
@ -186,7 +239,7 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
|
|||||||
):
|
):
|
||||||
for reservation in self.ec2_backend.reservations.values():
|
for reservation in self.ec2_backend.reservations.values():
|
||||||
for instance in reservation.instances:
|
for instance in reservation.instances:
|
||||||
tags = get_ec2_tags(instance.id)
|
tags = format_tags(self.ec2_backend.tags.get(instance.id, {}))
|
||||||
|
|
||||||
if not tags or not tag_filter(
|
if not tags or not tag_filter(
|
||||||
tags
|
tags
|
||||||
@ -204,7 +257,7 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
|
|||||||
or "ec2:network-interface" in resource_type_filters
|
or "ec2:network-interface" in resource_type_filters
|
||||||
):
|
):
|
||||||
for eni in self.ec2_backend.enis.values():
|
for eni in self.ec2_backend.enis.values():
|
||||||
tags = get_ec2_tags(eni.id)
|
tags = format_tags(self.ec2_backend.tags.get(eni.id, {}))
|
||||||
|
|
||||||
if not tags or not tag_filter(
|
if not tags or not tag_filter(
|
||||||
tags
|
tags
|
||||||
@ -225,7 +278,7 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
|
|||||||
):
|
):
|
||||||
for vpc in self.ec2_backend.groups.values():
|
for vpc in self.ec2_backend.groups.values():
|
||||||
for sg in vpc.values():
|
for sg in vpc.values():
|
||||||
tags = get_ec2_tags(sg.id)
|
tags = format_tags(self.ec2_backend.tags.get(sg.id, {}))
|
||||||
|
|
||||||
if not tags or not tag_filter(
|
if not tags or not tag_filter(
|
||||||
tags
|
tags
|
||||||
@ -243,7 +296,7 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
|
|||||||
or "ec2:snapshot" in resource_type_filters
|
or "ec2:snapshot" in resource_type_filters
|
||||||
):
|
):
|
||||||
for snapshot in self.ec2_backend.snapshots.values():
|
for snapshot in self.ec2_backend.snapshots.values():
|
||||||
tags = get_ec2_tags(snapshot.id)
|
tags = format_tags(self.ec2_backend.tags.get(snapshot.id, {}))
|
||||||
|
|
||||||
if not tags or not tag_filter(
|
if not tags or not tag_filter(
|
||||||
tags
|
tags
|
||||||
@ -263,7 +316,7 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
|
|||||||
or "ec2:volume" in resource_type_filters
|
or "ec2:volume" in resource_type_filters
|
||||||
):
|
):
|
||||||
for volume in self.ec2_backend.volumes.values():
|
for volume in self.ec2_backend.volumes.values():
|
||||||
tags = get_ec2_tags(volume.id)
|
tags = format_tags(self.ec2_backend.tags.get(volume.id, {}))
|
||||||
|
|
||||||
if not tags or not tag_filter(
|
if not tags or not tag_filter(
|
||||||
tags
|
tags
|
||||||
@ -312,15 +365,12 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
|
|||||||
# Kinesis
|
# Kinesis
|
||||||
|
|
||||||
# KMS
|
# KMS
|
||||||
def get_kms_tags(kms_key_id):
|
|
||||||
result = []
|
|
||||||
for tag in self.kms_backend.list_resource_tags(kms_key_id).get("Tags", []):
|
|
||||||
result.append({"Key": tag["TagKey"], "Value": tag["TagValue"]})
|
|
||||||
return result
|
|
||||||
|
|
||||||
if not resource_type_filters or "kms" in resource_type_filters:
|
if not resource_type_filters or "kms" in resource_type_filters:
|
||||||
for kms_key in self.kms_backend.list_keys():
|
for kms_key in self.kms_backend.list_keys():
|
||||||
tags = get_kms_tags(kms_key.id)
|
tags = format_tag_keys(
|
||||||
|
self.kms_backend.list_resource_tags(kms_key.id).get("Tags", []),
|
||||||
|
["TagKey", "TagValue"],
|
||||||
|
)
|
||||||
if not tag_filter(tags): # Skip if no tags, or invalid filter
|
if not tag_filter(tags): # Skip if no tags, or invalid filter
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -408,7 +458,7 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
|
|||||||
or "ec2:vpc" in resource_type_filters
|
or "ec2:vpc" in resource_type_filters
|
||||||
):
|
):
|
||||||
for vpc in self.ec2_backend.vpcs.values():
|
for vpc in self.ec2_backend.vpcs.values():
|
||||||
tags = get_ec2_tags(vpc.id)
|
tags = format_tags(self.ec2_backend.tags.get(vpc.id, {}))
|
||||||
if not tags or not tag_filter(
|
if not tags or not tag_filter(
|
||||||
tags
|
tags
|
||||||
): # Skip if no tags, or invalid filter
|
): # Skip if no tags, or invalid filter
|
||||||
@ -427,15 +477,9 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
|
|||||||
# VPC VPN Connection
|
# VPC VPN Connection
|
||||||
|
|
||||||
# Lambda Instance
|
# Lambda Instance
|
||||||
def transform_lambda_tags(dictTags):
|
|
||||||
result = []
|
|
||||||
for key, value in dictTags.items():
|
|
||||||
result.append({"Key": key, "Value": value})
|
|
||||||
return result
|
|
||||||
|
|
||||||
if not resource_type_filters or "lambda" in resource_type_filters:
|
if not resource_type_filters or "lambda" in resource_type_filters:
|
||||||
for f in self.lambda_backend.list_functions():
|
for f in self.lambda_backend.list_functions():
|
||||||
tags = transform_lambda_tags(f.tags)
|
tags = format_tags(f.tags)
|
||||||
if not tags or not tag_filter(tags):
|
if not tags or not tag_filter(tags):
|
||||||
continue
|
continue
|
||||||
yield {
|
yield {
|
||||||
@ -447,7 +491,7 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
|
|||||||
# Look at
|
# Look at
|
||||||
# https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html
|
# https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html
|
||||||
|
|
||||||
# Do S3, resource type s3
|
# S3
|
||||||
for bucket in self.s3_backend.buckets.values():
|
for bucket in self.s3_backend.buckets.values():
|
||||||
tags = self.s3_backend.tagger.get_tag_dict_for_resource(bucket.arn)
|
tags = self.s3_backend.tagger.get_tag_dict_for_resource(bucket.arn)
|
||||||
for key, _ in tags.items():
|
for key, _ in tags.items():
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import boto3
|
import boto3
|
||||||
|
import json
|
||||||
import sure # noqa # pylint: disable=unused-import
|
import sure # noqa # pylint: disable=unused-import
|
||||||
from moto import mock_ec2
|
from moto import mock_ec2
|
||||||
from moto import mock_elbv2
|
from moto import mock_elbv2
|
||||||
@ -8,10 +9,219 @@ from moto import mock_resourcegroupstaggingapi
|
|||||||
from moto import mock_s3
|
from moto import mock_s3
|
||||||
from moto import mock_lambda
|
from moto import mock_lambda
|
||||||
from moto import mock_iam
|
from moto import mock_iam
|
||||||
|
from moto import mock_cloudformation
|
||||||
|
from moto import mock_ecs
|
||||||
from botocore.client import ClientError
|
from botocore.client import ClientError
|
||||||
from tests import EXAMPLE_AMI_ID, EXAMPLE_AMI_ID2
|
from tests import EXAMPLE_AMI_ID, EXAMPLE_AMI_ID2
|
||||||
|
|
||||||
|
|
||||||
|
@mock_kms
|
||||||
|
@mock_cloudformation
|
||||||
|
@mock_resourcegroupstaggingapi
|
||||||
|
def test_get_resources_cloudformation():
|
||||||
|
|
||||||
|
template = {
|
||||||
|
"AWSTemplateFormatVersion": "2010-09-09",
|
||||||
|
"Resources": {"test": {"Type": "AWS::S3::Bucket"}},
|
||||||
|
}
|
||||||
|
template_json = json.dumps(template)
|
||||||
|
|
||||||
|
cf_client = boto3.client("cloudformation", region_name="us-east-1")
|
||||||
|
|
||||||
|
stack_one = cf_client.create_stack(
|
||||||
|
StackName="stack-1",
|
||||||
|
TemplateBody=template_json,
|
||||||
|
Tags=[{"Key": "tag", "Value": "one"}],
|
||||||
|
).get("StackId")
|
||||||
|
stack_two = cf_client.create_stack(
|
||||||
|
StackName="stack-2",
|
||||||
|
TemplateBody=template_json,
|
||||||
|
Tags=[{"Key": "tag", "Value": "two"}],
|
||||||
|
).get("StackId")
|
||||||
|
stack_three = cf_client.create_stack(
|
||||||
|
StackName="stack-3",
|
||||||
|
TemplateBody=template_json,
|
||||||
|
Tags=[{"Key": "tag", "Value": "three"}],
|
||||||
|
).get("StackId")
|
||||||
|
|
||||||
|
rgta_client = boto3.client("resourcegroupstaggingapi", region_name="us-east-1")
|
||||||
|
|
||||||
|
resp = rgta_client.get_resources(TagFilters=[{"Key": "tag", "Values": ["one"]}])
|
||||||
|
resp["ResourceTagMappingList"].should.have.length_of(1)
|
||||||
|
resp["ResourceTagMappingList"][0]["ResourceARN"].should.contain(stack_one)
|
||||||
|
|
||||||
|
resp = rgta_client.get_resources(
|
||||||
|
TagFilters=[{"Key": "tag", "Values": ["one", "three"]}]
|
||||||
|
)
|
||||||
|
resp["ResourceTagMappingList"].should.have.length_of(2)
|
||||||
|
resp["ResourceTagMappingList"][0]["ResourceARN"].should.contain(stack_one)
|
||||||
|
resp["ResourceTagMappingList"][1]["ResourceARN"].should.contain(stack_three)
|
||||||
|
|
||||||
|
kms_client = boto3.client("kms", region_name="us-east-1")
|
||||||
|
kms_client.create_key(
|
||||||
|
KeyUsage="ENCRYPT_DECRYPT", Tags=[{"TagKey": "tag", "TagValue": "two"}]
|
||||||
|
)
|
||||||
|
|
||||||
|
resp = rgta_client.get_resources(TagFilters=[{"Key": "tag", "Values": ["two"]}])
|
||||||
|
resp["ResourceTagMappingList"].should.have.length_of(2)
|
||||||
|
resp["ResourceTagMappingList"][0]["ResourceARN"].should.contain(stack_two)
|
||||||
|
resp["ResourceTagMappingList"][1]["ResourceARN"].should.contain("kms")
|
||||||
|
|
||||||
|
resp = rgta_client.get_resources(
|
||||||
|
ResourceTypeFilters=["cloudformation:stack"],
|
||||||
|
TagFilters=[{"Key": "tag", "Values": ["two"]}],
|
||||||
|
)
|
||||||
|
resp["ResourceTagMappingList"].should.have.length_of(1)
|
||||||
|
resp["ResourceTagMappingList"][0]["ResourceARN"].should.contain(stack_two)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ecs
|
||||||
|
@mock_ec2
|
||||||
|
@mock_resourcegroupstaggingapi
|
||||||
|
def test_get_resources_ecs():
|
||||||
|
|
||||||
|
# ecs:cluster
|
||||||
|
client = boto3.client("ecs", region_name="us-east-1")
|
||||||
|
cluster_one = (
|
||||||
|
client.create_cluster(
|
||||||
|
clusterName="cluster-a", tags=[{"key": "tag", "value": "a tag"}]
|
||||||
|
)
|
||||||
|
.get("cluster")
|
||||||
|
.get("clusterArn")
|
||||||
|
)
|
||||||
|
cluster_two = (
|
||||||
|
client.create_cluster(
|
||||||
|
clusterName="cluster-b", tags=[{"key": "tag", "value": "b tag"}]
|
||||||
|
)
|
||||||
|
.get("cluster")
|
||||||
|
.get("clusterArn")
|
||||||
|
)
|
||||||
|
|
||||||
|
rgta_client = boto3.client("resourcegroupstaggingapi", region_name="us-east-1")
|
||||||
|
resp = rgta_client.get_resources(TagFilters=[{"Key": "tag", "Values": ["a tag"]}])
|
||||||
|
resp["ResourceTagMappingList"].should.have.length_of(1)
|
||||||
|
resp["ResourceTagMappingList"][0]["ResourceARN"].should.contain(cluster_one)
|
||||||
|
|
||||||
|
# ecs:service
|
||||||
|
service_one = (
|
||||||
|
client.create_service(
|
||||||
|
cluster=cluster_one,
|
||||||
|
serviceName="service-a",
|
||||||
|
tags=[{"key": "tag", "value": "a tag"}],
|
||||||
|
)
|
||||||
|
.get("service")
|
||||||
|
.get("serviceArn")
|
||||||
|
)
|
||||||
|
|
||||||
|
service_two = (
|
||||||
|
client.create_service(
|
||||||
|
cluster=cluster_two,
|
||||||
|
serviceName="service-b",
|
||||||
|
tags=[{"key": "tag", "value": "b tag"}],
|
||||||
|
)
|
||||||
|
.get("service")
|
||||||
|
.get("serviceArn")
|
||||||
|
)
|
||||||
|
|
||||||
|
resp = rgta_client.get_resources(TagFilters=[{"Key": "tag", "Values": ["a tag"]}])
|
||||||
|
resp["ResourceTagMappingList"].should.have.length_of(2)
|
||||||
|
resp["ResourceTagMappingList"][0]["ResourceARN"].should.contain(service_one)
|
||||||
|
resp["ResourceTagMappingList"][1]["ResourceARN"].should.contain(cluster_one)
|
||||||
|
|
||||||
|
resp = rgta_client.get_resources(
|
||||||
|
ResourceTypeFilters=["ecs:cluster"],
|
||||||
|
TagFilters=[{"Key": "tag", "Values": ["b tag"]}],
|
||||||
|
)
|
||||||
|
resp["ResourceTagMappingList"].should.have.length_of(1)
|
||||||
|
resp["ResourceTagMappingList"][0]["ResourceARN"].should_not.contain(service_two)
|
||||||
|
resp["ResourceTagMappingList"][0]["ResourceARN"].should.contain(cluster_two)
|
||||||
|
|
||||||
|
resp = rgta_client.get_resources(
|
||||||
|
ResourceTypeFilters=["ecs:service"],
|
||||||
|
TagFilters=[{"Key": "tag", "Values": ["b tag"]}],
|
||||||
|
)
|
||||||
|
resp["ResourceTagMappingList"].should.have.length_of(1)
|
||||||
|
resp["ResourceTagMappingList"][0]["ResourceARN"].should.contain(service_two)
|
||||||
|
resp["ResourceTagMappingList"][0]["ResourceARN"].should_not.contain(cluster_two)
|
||||||
|
|
||||||
|
# ecs:task
|
||||||
|
resp = client.register_task_definition(
|
||||||
|
family="test_ecs_task",
|
||||||
|
containerDefinitions=[
|
||||||
|
{
|
||||||
|
"name": "hello_world",
|
||||||
|
"image": "docker/hello-world:latest",
|
||||||
|
"cpu": 1024,
|
||||||
|
"memory": 400,
|
||||||
|
"essential": True,
|
||||||
|
"environment": [
|
||||||
|
{"name": "AWS_ACCESS_KEY_ID", "value": "SOME_ACCESS_KEY"}
|
||||||
|
],
|
||||||
|
"logConfiguration": {"logDriver": "json-file"},
|
||||||
|
}
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
ec2_client = boto3.client("ec2", region_name="us-east-1")
|
||||||
|
vpc = ec2_client.create_vpc(CidrBlock="10.0.0.0/16").get("Vpc").get("VpcId")
|
||||||
|
subnet = (
|
||||||
|
ec2_client.create_subnet(VpcId=vpc, CidrBlock="10.0.0.0/18")
|
||||||
|
.get("Subnet")
|
||||||
|
.get("SubnetId")
|
||||||
|
)
|
||||||
|
sg = ec2_client.create_security_group(
|
||||||
|
VpcId=vpc, GroupName="test-ecs", Description="moto ecs"
|
||||||
|
).get("GroupId")
|
||||||
|
|
||||||
|
task_one = (
|
||||||
|
client.run_task(
|
||||||
|
cluster="cluster-a",
|
||||||
|
taskDefinition="test_ecs_task",
|
||||||
|
launchType="FARGATE",
|
||||||
|
networkConfiguration={
|
||||||
|
"awsvpcConfiguration": {
|
||||||
|
"subnets": [subnet],
|
||||||
|
"securityGroups": [sg],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tags=[{"key": "tag", "value": "a tag"}],
|
||||||
|
)
|
||||||
|
.get("tasks")[0]
|
||||||
|
.get("taskArn")
|
||||||
|
)
|
||||||
|
|
||||||
|
task_two = (
|
||||||
|
client.run_task(
|
||||||
|
cluster="cluster-b",
|
||||||
|
taskDefinition="test_ecs_task",
|
||||||
|
launchType="FARGATE",
|
||||||
|
networkConfiguration={
|
||||||
|
"awsvpcConfiguration": {
|
||||||
|
"subnets": [subnet],
|
||||||
|
"securityGroups": [sg],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tags=[{"key": "tag", "value": "b tag"}],
|
||||||
|
)
|
||||||
|
.get("tasks")[0]
|
||||||
|
.get("taskArn")
|
||||||
|
)
|
||||||
|
|
||||||
|
resp = rgta_client.get_resources(TagFilters=[{"Key": "tag", "Values": ["b tag"]}])
|
||||||
|
resp["ResourceTagMappingList"].should.have.length_of(3)
|
||||||
|
resp["ResourceTagMappingList"][0]["ResourceARN"].should.contain(service_two)
|
||||||
|
resp["ResourceTagMappingList"][1]["ResourceARN"].should.contain(cluster_two)
|
||||||
|
resp["ResourceTagMappingList"][2]["ResourceARN"].should.contain(task_two)
|
||||||
|
|
||||||
|
resp = rgta_client.get_resources(
|
||||||
|
ResourceTypeFilters=["ecs:task"],
|
||||||
|
TagFilters=[{"Key": "tag", "Values": ["a tag"]}],
|
||||||
|
)
|
||||||
|
resp["ResourceTagMappingList"].should.have.length_of(1)
|
||||||
|
resp["ResourceTagMappingList"][0]["ResourceARN"].should.contain(task_one)
|
||||||
|
resp["ResourceTagMappingList"][0]["ResourceARN"].should_not.contain(task_two)
|
||||||
|
|
||||||
|
|
||||||
@mock_rds
|
@mock_rds
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
@mock_resourcegroupstaggingapi
|
@mock_resourcegroupstaggingapi
|
||||||
@ -422,50 +632,6 @@ def test_get_resources_rds():
|
|||||||
assert_response(resp, 2)
|
assert_response(resp, 2)
|
||||||
|
|
||||||
|
|
||||||
@mock_rds
|
|
||||||
@mock_resourcegroupstaggingapi
|
|
||||||
def test_get_resources_rds_clusters():
|
|
||||||
client = boto3.client("rds", region_name="us-west-2")
|
|
||||||
resources_tagged = []
|
|
||||||
resources_untagged = []
|
|
||||||
for i in range(3):
|
|
||||||
cluster = client.create_db_cluster(
|
|
||||||
DBClusterIdentifier=f"db-cluster-{i}",
|
|
||||||
Engine="postgres",
|
|
||||||
MasterUsername="admin",
|
|
||||||
MasterUserPassword="P@ssw0rd!",
|
|
||||||
CopyTagsToSnapshot=True if i else False,
|
|
||||||
Tags=[{"Key": "test", "Value": f"value-{i}"}] if i else [],
|
|
||||||
).get("DBCluster")
|
|
||||||
snapshot = client.create_db_cluster_snapshot(
|
|
||||||
DBClusterIdentifier=cluster["DBClusterIdentifier"],
|
|
||||||
DBClusterSnapshotIdentifier=f"snapshot-{i}",
|
|
||||||
).get("DBClusterSnapshot")
|
|
||||||
group = resources_tagged if i else resources_untagged
|
|
||||||
group.append(cluster["DBClusterArn"])
|
|
||||||
group.append(snapshot["DBClusterSnapshotArn"])
|
|
||||||
|
|
||||||
def assert_response(response, expected_count, resource_type=None):
|
|
||||||
results = response.get("ResourceTagMappingList", [])
|
|
||||||
results.should.have.length_of(expected_count)
|
|
||||||
for item in results:
|
|
||||||
arn = item["ResourceARN"]
|
|
||||||
arn.should.be.within(resources_tagged)
|
|
||||||
arn.should_not.be.within(resources_untagged)
|
|
||||||
if resource_type:
|
|
||||||
sure.this(f":{resource_type}:").should.be.within(arn)
|
|
||||||
|
|
||||||
rtapi = boto3.client("resourcegroupstaggingapi", region_name="us-west-2")
|
|
||||||
resp = rtapi.get_resources(ResourceTypeFilters=["rds"])
|
|
||||||
assert_response(resp, 4)
|
|
||||||
resp = rtapi.get_resources(ResourceTypeFilters=["rds:cluster"])
|
|
||||||
assert_response(resp, 2, resource_type="cluster")
|
|
||||||
resp = rtapi.get_resources(ResourceTypeFilters=["rds:cluster-snapshot"])
|
|
||||||
assert_response(resp, 2, resource_type="cluster-snapshot")
|
|
||||||
resp = rtapi.get_resources(TagFilters=[{"Key": "test", "Values": ["value-1"]}])
|
|
||||||
assert_response(resp, 2)
|
|
||||||
|
|
||||||
|
|
||||||
@mock_lambda
|
@mock_lambda
|
||||||
@mock_resourcegroupstaggingapi
|
@mock_resourcegroupstaggingapi
|
||||||
@mock_iam
|
@mock_iam
|
||||||
|
Loading…
x
Reference in New Issue
Block a user