Run black on moto & test directories.
This commit is contained in:
parent
c820395dbf
commit
96e5b1993d
507 changed files with 52541 additions and 47814 deletions
|
|
@ -2,5 +2,5 @@ from __future__ import unicode_literals
|
|||
from .models import resourcegroupstaggingapi_backends
|
||||
from ..core.models import base_decorator
|
||||
|
||||
resourcegroupstaggingapi_backend = resourcegroupstaggingapi_backends['us-east-1']
|
||||
resourcegroupstaggingapi_backend = resourcegroupstaggingapi_backends["us-east-1"]
|
||||
mock_resourcegroupstaggingapi = base_decorator(resourcegroupstaggingapi_backends)
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
|
|||
"""
|
||||
:rtype: moto.s3.models.S3Backend
|
||||
"""
|
||||
return s3_backends['global']
|
||||
return s3_backends["global"]
|
||||
|
||||
@property
|
||||
def ec2_backend(self):
|
||||
|
|
@ -114,16 +114,18 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
|
|||
# TODO move these to their respective backends
|
||||
filters = [lambda t, v: True]
|
||||
for tag_filter_dict in tag_filters:
|
||||
values = tag_filter_dict.get('Values', [])
|
||||
values = tag_filter_dict.get("Values", [])
|
||||
if len(values) == 0:
|
||||
# Check key matches
|
||||
filters.append(lambda t, v: t == tag_filter_dict['Key'])
|
||||
filters.append(lambda t, v: t == tag_filter_dict["Key"])
|
||||
elif len(values) == 1:
|
||||
# Check its exactly the same as key, value
|
||||
filters.append(lambda t, v: t == tag_filter_dict['Key'] and v == values[0])
|
||||
filters.append(
|
||||
lambda t, v: t == tag_filter_dict["Key"] and v == values[0]
|
||||
)
|
||||
else:
|
||||
# Check key matches and value is one of the provided values
|
||||
filters.append(lambda t, v: t == tag_filter_dict['Key'] and v in values)
|
||||
filters.append(lambda t, v: t == tag_filter_dict["Key"] and v in values)
|
||||
|
||||
def tag_filter(tag_list):
|
||||
result = []
|
||||
|
|
@ -131,7 +133,7 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
|
|||
for tag in tag_list:
|
||||
temp_result = []
|
||||
for f in filters:
|
||||
f_result = f(tag['Key'], tag['Value'])
|
||||
f_result = f(tag["Key"], tag["Value"])
|
||||
temp_result.append(f_result)
|
||||
result.append(all(temp_result))
|
||||
|
||||
|
|
@ -140,82 +142,150 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
|
|||
return True
|
||||
|
||||
# Do S3, resource type 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():
|
||||
tags = []
|
||||
for tag in bucket.tags.tag_set.tags:
|
||||
tags.append({'Key': tag.key, 'Value': tag.value})
|
||||
tags.append({"Key": tag.key, "Value": tag.value})
|
||||
|
||||
if not tags or not tag_filter(tags): # Skip if no tags, or invalid filter
|
||||
if not tags or not tag_filter(
|
||||
tags
|
||||
): # Skip if no tags, or invalid filter
|
||||
continue
|
||||
yield {'ResourceARN': 'arn:aws:s3:::' + bucket.name, 'Tags': tags}
|
||||
yield {"ResourceARN": "arn:aws:s3:::" + bucket.name, "Tags": tags}
|
||||
|
||||
# EC2 tags
|
||||
def get_ec2_tags(res_id):
|
||||
result = []
|
||||
for key, value in self.ec2_backend.tags.get(res_id, {}).items():
|
||||
result.append({'Key': key, 'Value': value})
|
||||
result.append({"Key": key, "Value": value})
|
||||
return result
|
||||
|
||||
# EC2 AMI, resource type ec2:image
|
||||
if not resource_type_filters or 'ec2' in resource_type_filters or 'ec2:image' in resource_type_filters:
|
||||
if (
|
||||
not resource_type_filters
|
||||
or "ec2" in resource_type_filters
|
||||
or "ec2:image" in resource_type_filters
|
||||
):
|
||||
for ami in self.ec2_backend.amis.values():
|
||||
tags = get_ec2_tags(ami.id)
|
||||
|
||||
if not tags or not tag_filter(tags): # Skip if no tags, or invalid filter
|
||||
if not tags or not tag_filter(
|
||||
tags
|
||||
): # Skip if no tags, or invalid filter
|
||||
continue
|
||||
yield {'ResourceARN': 'arn:aws:ec2:{0}::image/{1}'.format(self.region_name, ami.id), 'Tags': tags}
|
||||
yield {
|
||||
"ResourceARN": "arn:aws:ec2:{0}::image/{1}".format(
|
||||
self.region_name, ami.id
|
||||
),
|
||||
"Tags": tags,
|
||||
}
|
||||
|
||||
# EC2 Instance, resource type ec2:instance
|
||||
if not resource_type_filters or 'ec2' in resource_type_filters or 'ec2:instance' in resource_type_filters:
|
||||
if (
|
||||
not resource_type_filters
|
||||
or "ec2" in resource_type_filters
|
||||
or "ec2:instance" in resource_type_filters
|
||||
):
|
||||
for reservation in self.ec2_backend.reservations.values():
|
||||
for instance in reservation.instances:
|
||||
tags = get_ec2_tags(instance.id)
|
||||
|
||||
if not tags or not tag_filter(tags): # Skip if no tags, or invalid filter
|
||||
if not tags or not tag_filter(
|
||||
tags
|
||||
): # Skip if no tags, or invalid filter
|
||||
continue
|
||||
yield {'ResourceARN': 'arn:aws:ec2:{0}::instance/{1}'.format(self.region_name, instance.id), 'Tags': tags}
|
||||
yield {
|
||||
"ResourceARN": "arn:aws:ec2:{0}::instance/{1}".format(
|
||||
self.region_name, instance.id
|
||||
),
|
||||
"Tags": tags,
|
||||
}
|
||||
|
||||
# EC2 NetworkInterface, resource type ec2:network-interface
|
||||
if not resource_type_filters or 'ec2' in resource_type_filters or 'ec2:network-interface' in resource_type_filters:
|
||||
if (
|
||||
not resource_type_filters
|
||||
or "ec2" in resource_type_filters
|
||||
or "ec2:network-interface" in resource_type_filters
|
||||
):
|
||||
for eni in self.ec2_backend.enis.values():
|
||||
tags = get_ec2_tags(eni.id)
|
||||
|
||||
if not tags or not tag_filter(tags): # Skip if no tags, or invalid filter
|
||||
if not tags or not tag_filter(
|
||||
tags
|
||||
): # Skip if no tags, or invalid filter
|
||||
continue
|
||||
yield {'ResourceARN': 'arn:aws:ec2:{0}::network-interface/{1}'.format(self.region_name, eni.id), 'Tags': tags}
|
||||
yield {
|
||||
"ResourceARN": "arn:aws:ec2:{0}::network-interface/{1}".format(
|
||||
self.region_name, eni.id
|
||||
),
|
||||
"Tags": tags,
|
||||
}
|
||||
|
||||
# TODO EC2 ReservedInstance
|
||||
|
||||
# EC2 SecurityGroup, resource type ec2:security-group
|
||||
if not resource_type_filters or 'ec2' in resource_type_filters or 'ec2:security-group' in resource_type_filters:
|
||||
if (
|
||||
not resource_type_filters
|
||||
or "ec2" in resource_type_filters
|
||||
or "ec2:security-group" in resource_type_filters
|
||||
):
|
||||
for vpc in self.ec2_backend.groups.values():
|
||||
for sg in vpc.values():
|
||||
tags = get_ec2_tags(sg.id)
|
||||
|
||||
if not tags or not tag_filter(tags): # Skip if no tags, or invalid filter
|
||||
if not tags or not tag_filter(
|
||||
tags
|
||||
): # Skip if no tags, or invalid filter
|
||||
continue
|
||||
yield {'ResourceARN': 'arn:aws:ec2:{0}::security-group/{1}'.format(self.region_name, sg.id), 'Tags': tags}
|
||||
yield {
|
||||
"ResourceARN": "arn:aws:ec2:{0}::security-group/{1}".format(
|
||||
self.region_name, sg.id
|
||||
),
|
||||
"Tags": tags,
|
||||
}
|
||||
|
||||
# EC2 Snapshot, resource type ec2:snapshot
|
||||
if not resource_type_filters or 'ec2' in resource_type_filters or 'ec2:snapshot' in resource_type_filters:
|
||||
if (
|
||||
not resource_type_filters
|
||||
or "ec2" in resource_type_filters
|
||||
or "ec2:snapshot" in resource_type_filters
|
||||
):
|
||||
for snapshot in self.ec2_backend.snapshots.values():
|
||||
tags = get_ec2_tags(snapshot.id)
|
||||
|
||||
if not tags or not tag_filter(tags): # Skip if no tags, or invalid filter
|
||||
if not tags or not tag_filter(
|
||||
tags
|
||||
): # Skip if no tags, or invalid filter
|
||||
continue
|
||||
yield {'ResourceARN': 'arn:aws:ec2:{0}::snapshot/{1}'.format(self.region_name, snapshot.id), 'Tags': tags}
|
||||
yield {
|
||||
"ResourceARN": "arn:aws:ec2:{0}::snapshot/{1}".format(
|
||||
self.region_name, snapshot.id
|
||||
),
|
||||
"Tags": tags,
|
||||
}
|
||||
|
||||
# TODO EC2 SpotInstanceRequest
|
||||
|
||||
# EC2 Volume, resource type ec2:volume
|
||||
if not resource_type_filters or 'ec2' in resource_type_filters or 'ec2:volume' in resource_type_filters:
|
||||
if (
|
||||
not resource_type_filters
|
||||
or "ec2" in resource_type_filters
|
||||
or "ec2:volume" in resource_type_filters
|
||||
):
|
||||
for volume in self.ec2_backend.volumes.values():
|
||||
tags = get_ec2_tags(volume.id)
|
||||
|
||||
if not tags or not tag_filter(tags): # Skip if no tags, or invalid filter
|
||||
if not tags or not tag_filter(
|
||||
tags
|
||||
): # Skip if no tags, or invalid filter
|
||||
continue
|
||||
yield {'ResourceARN': 'arn:aws:ec2:{0}::volume/{1}'.format(self.region_name, volume.id), 'Tags': tags}
|
||||
yield {
|
||||
"ResourceARN": "arn:aws:ec2:{0}::volume/{1}".format(
|
||||
self.region_name, volume.id
|
||||
),
|
||||
"Tags": tags,
|
||||
}
|
||||
|
||||
# TODO add these to the keys and values functions / combine functions
|
||||
# ELB
|
||||
|
|
@ -223,16 +293,20 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
|
|||
def get_elbv2_tags(arn):
|
||||
result = []
|
||||
for key, value in self.elbv2_backend.load_balancers[elb.arn].tags.items():
|
||||
result.append({'Key': key, 'Value': value})
|
||||
result.append({"Key": key, "Value": value})
|
||||
return result
|
||||
|
||||
if not resource_type_filters or 'elasticloadbalancer' in resource_type_filters or 'elasticloadbalancer:loadbalancer' in resource_type_filters:
|
||||
if (
|
||||
not resource_type_filters
|
||||
or "elasticloadbalancer" in resource_type_filters
|
||||
or "elasticloadbalancer:loadbalancer" in resource_type_filters
|
||||
):
|
||||
for elb in self.elbv2_backend.load_balancers.values():
|
||||
tags = get_elbv2_tags(elb.arn)
|
||||
if not tag_filter(tags): # Skip if no tags, or invalid filter
|
||||
continue
|
||||
|
||||
yield {'ResourceARN': '{0}'.format(elb.arn), 'Tags': tags}
|
||||
yield {"ResourceARN": "{0}".format(elb.arn), "Tags": tags}
|
||||
|
||||
# EMR Cluster
|
||||
|
||||
|
|
@ -244,16 +318,16 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
|
|||
def get_kms_tags(kms_key_id):
|
||||
result = []
|
||||
for tag in self.kms_backend.list_resource_tags(kms_key_id):
|
||||
result.append({'Key': tag['TagKey'], 'Value': tag['TagValue']})
|
||||
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():
|
||||
tags = get_kms_tags(kms_key.id)
|
||||
if not tag_filter(tags): # Skip if no tags, or invalid filter
|
||||
continue
|
||||
|
||||
yield {'ResourceARN': '{0}'.format(kms_key.arn), 'Tags': tags}
|
||||
yield {"ResourceARN": "{0}".format(kms_key.arn), "Tags": tags}
|
||||
|
||||
# RDS Instance
|
||||
# RDS Reserved Database Instance
|
||||
|
|
@ -387,25 +461,37 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
|
|||
for value in get_ec2_values(volume.id):
|
||||
yield value
|
||||
|
||||
def get_resources(self, pagination_token=None,
|
||||
resources_per_page=50, tags_per_page=100,
|
||||
tag_filters=None, resource_type_filters=None):
|
||||
def get_resources(
|
||||
self,
|
||||
pagination_token=None,
|
||||
resources_per_page=50,
|
||||
tags_per_page=100,
|
||||
tag_filters=None,
|
||||
resource_type_filters=None,
|
||||
):
|
||||
# Simple range checking
|
||||
if 100 >= tags_per_page >= 500:
|
||||
raise RESTError('InvalidParameterException', 'TagsPerPage must be between 100 and 500')
|
||||
raise RESTError(
|
||||
"InvalidParameterException", "TagsPerPage must be between 100 and 500"
|
||||
)
|
||||
if 1 >= resources_per_page >= 50:
|
||||
raise RESTError('InvalidParameterException', 'ResourcesPerPage must be between 1 and 50')
|
||||
raise RESTError(
|
||||
"InvalidParameterException", "ResourcesPerPage must be between 1 and 50"
|
||||
)
|
||||
|
||||
# If we have a token, go and find the respective generator, or error
|
||||
if pagination_token:
|
||||
if pagination_token not in self._pages:
|
||||
raise RESTError('PaginationTokenExpiredException', 'Token does not exist')
|
||||
raise RESTError(
|
||||
"PaginationTokenExpiredException", "Token does not exist"
|
||||
)
|
||||
|
||||
generator = self._pages[pagination_token]['gen']
|
||||
left_over = self._pages[pagination_token]['misc']
|
||||
generator = self._pages[pagination_token]["gen"]
|
||||
left_over = self._pages[pagination_token]["misc"]
|
||||
else:
|
||||
generator = self._get_resources_generator(tag_filters=tag_filters,
|
||||
resource_type_filters=resource_type_filters)
|
||||
generator = self._get_resources_generator(
|
||||
tag_filters=tag_filters, resource_type_filters=resource_type_filters
|
||||
)
|
||||
left_over = None
|
||||
|
||||
result = []
|
||||
|
|
@ -414,13 +500,13 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
|
|||
if left_over:
|
||||
result.append(left_over)
|
||||
current_resources += 1
|
||||
current_tags += len(left_over['Tags'])
|
||||
current_tags += len(left_over["Tags"])
|
||||
|
||||
try:
|
||||
while True:
|
||||
# Generator format: [{'ResourceARN': str, 'Tags': [{'Key': str, 'Value': str]}, ...]
|
||||
next_item = six.next(generator)
|
||||
resource_tags = len(next_item['Tags'])
|
||||
resource_tags = len(next_item["Tags"])
|
||||
|
||||
if current_resources >= resources_per_page:
|
||||
break
|
||||
|
|
@ -438,7 +524,7 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
|
|||
|
||||
# Didn't hit StopIteration so there's stuff left in generator
|
||||
new_token = str(uuid.uuid4())
|
||||
self._pages[new_token] = {'gen': generator, 'misc': next_item}
|
||||
self._pages[new_token] = {"gen": generator, "misc": next_item}
|
||||
|
||||
# Token used up, might as well bin now, if you call it again your an idiot
|
||||
if pagination_token:
|
||||
|
|
@ -450,10 +536,12 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
|
|||
|
||||
if pagination_token:
|
||||
if pagination_token not in self._pages:
|
||||
raise RESTError('PaginationTokenExpiredException', 'Token does not exist')
|
||||
raise RESTError(
|
||||
"PaginationTokenExpiredException", "Token does not exist"
|
||||
)
|
||||
|
||||
generator = self._pages[pagination_token]['gen']
|
||||
left_over = self._pages[pagination_token]['misc']
|
||||
generator = self._pages[pagination_token]["gen"]
|
||||
left_over = self._pages[pagination_token]["misc"]
|
||||
else:
|
||||
generator = self._get_tag_keys_generator()
|
||||
left_over = None
|
||||
|
|
@ -482,7 +570,7 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
|
|||
|
||||
# Didn't hit StopIteration so there's stuff left in generator
|
||||
new_token = str(uuid.uuid4())
|
||||
self._pages[new_token] = {'gen': generator, 'misc': next_item}
|
||||
self._pages[new_token] = {"gen": generator, "misc": next_item}
|
||||
|
||||
# Token used up, might as well bin now, if you call it again your an idiot
|
||||
if pagination_token:
|
||||
|
|
@ -494,10 +582,12 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
|
|||
|
||||
if pagination_token:
|
||||
if pagination_token not in self._pages:
|
||||
raise RESTError('PaginationTokenExpiredException', 'Token does not exist')
|
||||
raise RESTError(
|
||||
"PaginationTokenExpiredException", "Token does not exist"
|
||||
)
|
||||
|
||||
generator = self._pages[pagination_token]['gen']
|
||||
left_over = self._pages[pagination_token]['misc']
|
||||
generator = self._pages[pagination_token]["gen"]
|
||||
left_over = self._pages[pagination_token]["misc"]
|
||||
else:
|
||||
generator = self._get_tag_values_generator(key)
|
||||
left_over = None
|
||||
|
|
@ -526,7 +616,7 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
|
|||
|
||||
# Didn't hit StopIteration so there's stuff left in generator
|
||||
new_token = str(uuid.uuid4())
|
||||
self._pages[new_token] = {'gen': generator, 'misc': next_item}
|
||||
self._pages[new_token] = {"gen": generator, "misc": next_item}
|
||||
|
||||
# Token used up, might as well bin now, if you call it again your an idiot
|
||||
if pagination_token:
|
||||
|
|
@ -546,5 +636,9 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
|
|||
# return failed_resources_map
|
||||
|
||||
|
||||
available_regions = boto3.session.Session().get_available_regions("resourcegroupstaggingapi")
|
||||
resourcegroupstaggingapi_backends = {region: ResourceGroupsTaggingAPIBackend(region) for region in available_regions}
|
||||
available_regions = boto3.session.Session().get_available_regions(
|
||||
"resourcegroupstaggingapi"
|
||||
)
|
||||
resourcegroupstaggingapi_backends = {
|
||||
region: ResourceGroupsTaggingAPIBackend(region) for region in available_regions
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import json
|
|||
|
||||
|
||||
class ResourceGroupsTaggingAPIResponse(BaseResponse):
|
||||
SERVICE_NAME = 'resourcegroupstaggingapi'
|
||||
SERVICE_NAME = "resourcegroupstaggingapi"
|
||||
|
||||
@property
|
||||
def backend(self):
|
||||
|
|
@ -32,25 +32,21 @@ class ResourceGroupsTaggingAPIResponse(BaseResponse):
|
|||
)
|
||||
|
||||
# Format tag response
|
||||
response = {
|
||||
'ResourceTagMappingList': resource_tag_mapping_list
|
||||
}
|
||||
response = {"ResourceTagMappingList": resource_tag_mapping_list}
|
||||
if pagination_token:
|
||||
response['PaginationToken'] = pagination_token
|
||||
response["PaginationToken"] = pagination_token
|
||||
|
||||
return json.dumps(response)
|
||||
|
||||
def get_tag_keys(self):
|
||||
pagination_token = self._get_param("PaginationToken")
|
||||
pagination_token, tag_keys = self.backend.get_tag_keys(
|
||||
pagination_token=pagination_token,
|
||||
pagination_token=pagination_token
|
||||
)
|
||||
|
||||
response = {
|
||||
'TagKeys': tag_keys
|
||||
}
|
||||
response = {"TagKeys": tag_keys}
|
||||
if pagination_token:
|
||||
response['PaginationToken'] = pagination_token
|
||||
response["PaginationToken"] = pagination_token
|
||||
|
||||
return json.dumps(response)
|
||||
|
||||
|
|
@ -58,15 +54,12 @@ class ResourceGroupsTaggingAPIResponse(BaseResponse):
|
|||
pagination_token = self._get_param("PaginationToken")
|
||||
key = self._get_param("Key")
|
||||
pagination_token, tag_values = self.backend.get_tag_values(
|
||||
pagination_token=pagination_token,
|
||||
key=key,
|
||||
pagination_token=pagination_token, key=key
|
||||
)
|
||||
|
||||
response = {
|
||||
'TagValues': tag_values
|
||||
}
|
||||
response = {"TagValues": tag_values}
|
||||
if pagination_token:
|
||||
response['PaginationToken'] = pagination_token
|
||||
response["PaginationToken"] = pagination_token
|
||||
|
||||
return json.dumps(response)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,6 @@
|
|||
from __future__ import unicode_literals
|
||||
from .responses import ResourceGroupsTaggingAPIResponse
|
||||
|
||||
url_bases = [
|
||||
"https?://tagging.(.+).amazonaws.com",
|
||||
]
|
||||
url_bases = ["https?://tagging.(.+).amazonaws.com"]
|
||||
|
||||
url_paths = {
|
||||
'{0}/$': ResourceGroupsTaggingAPIResponse.dispatch,
|
||||
}
|
||||
url_paths = {"{0}/$": ResourceGroupsTaggingAPIResponse.dispatch}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue