Get standalone server mode working for all tests.
This commit is contained in:
parent
cb28eeefbb
commit
81836b6981
78 changed files with 957 additions and 783 deletions
|
|
@ -1,4 +1,6 @@
|
|||
from __future__ import unicode_literals
|
||||
from .models import route53_backend
|
||||
|
||||
route53_backends = {"global": route53_backend}
|
||||
mock_route53 = route53_backend.decorator
|
||||
mock_route53_deprecated = route53_backend.deprecated_decorator
|
||||
|
|
|
|||
|
|
@ -1,174 +1,186 @@
|
|||
from __future__ import unicode_literals
|
||||
from jinja2 import Template
|
||||
from six.moves.urllib.parse import parse_qs, urlparse
|
||||
|
||||
from moto.core.responses import BaseResponse
|
||||
from .models import route53_backend
|
||||
import xmltodict
|
||||
|
||||
|
||||
def list_or_create_hostzone_response(request, full_url, headers):
|
||||
class Route53 (BaseResponse):
|
||||
def list_or_create_hostzone_response(self, request, full_url, headers):
|
||||
self.setup_class(request, full_url, headers)
|
||||
|
||||
if request.method == "POST":
|
||||
elements = xmltodict.parse(request.body)
|
||||
if "HostedZoneConfig" in elements["CreateHostedZoneRequest"]:
|
||||
comment = elements["CreateHostedZoneRequest"]["HostedZoneConfig"]["Comment"]
|
||||
try:
|
||||
# in boto3, this field is set directly in the xml
|
||||
private_zone = elements["CreateHostedZoneRequest"]["HostedZoneConfig"]["PrivateZone"]
|
||||
except KeyError:
|
||||
# if a VPC subsection is only included in xmls params when private_zone=True,
|
||||
# see boto: boto/route53/connection.py
|
||||
private_zone = 'VPC' in elements["CreateHostedZoneRequest"]
|
||||
else:
|
||||
comment = None
|
||||
private_zone = False
|
||||
if request.method == "POST":
|
||||
elements = xmltodict.parse(self.body)
|
||||
if "HostedZoneConfig" in elements["CreateHostedZoneRequest"]:
|
||||
comment = elements["CreateHostedZoneRequest"]["HostedZoneConfig"]["Comment"]
|
||||
try:
|
||||
# in boto3, this field is set directly in the xml
|
||||
private_zone = elements["CreateHostedZoneRequest"]["HostedZoneConfig"]["PrivateZone"]
|
||||
except KeyError:
|
||||
# if a VPC subsection is only included in xmls params when private_zone=True,
|
||||
# see boto: boto/route53/connection.py
|
||||
private_zone = 'VPC' in elements["CreateHostedZoneRequest"]
|
||||
else:
|
||||
comment = None
|
||||
private_zone = False
|
||||
|
||||
name = elements["CreateHostedZoneRequest"]["Name"]
|
||||
|
||||
if name[-1] != ".":
|
||||
name += "."
|
||||
|
||||
new_zone = route53_backend.create_hosted_zone(
|
||||
name,
|
||||
comment=comment,
|
||||
private_zone=private_zone,
|
||||
)
|
||||
template = Template(CREATE_HOSTED_ZONE_RESPONSE)
|
||||
return 201, headers, template.render(zone=new_zone)
|
||||
|
||||
elif request.method == "GET":
|
||||
all_zones = route53_backend.get_all_hosted_zones()
|
||||
template = Template(LIST_HOSTED_ZONES_RESPONSE)
|
||||
return 200, headers, template.render(zones=all_zones)
|
||||
|
||||
|
||||
name = elements["CreateHostedZoneRequest"]["Name"]
|
||||
def get_or_delete_hostzone_response(self, request, full_url, headers):
|
||||
self.setup_class(request, full_url, headers)
|
||||
parsed_url = urlparse(full_url)
|
||||
zoneid = parsed_url.path.rstrip('/').rsplit('/', 1)[1]
|
||||
the_zone = route53_backend.get_hosted_zone(zoneid)
|
||||
if not the_zone:
|
||||
return 404, headers, "Zone %s not Found" % zoneid
|
||||
|
||||
if name[-1] != ".":
|
||||
name += "."
|
||||
if request.method == "GET":
|
||||
template = Template(GET_HOSTED_ZONE_RESPONSE)
|
||||
|
||||
new_zone = route53_backend.create_hosted_zone(
|
||||
name,
|
||||
comment=comment,
|
||||
private_zone=private_zone,
|
||||
)
|
||||
template = Template(CREATE_HOSTED_ZONE_RESPONSE)
|
||||
return 201, headers, template.render(zone=new_zone)
|
||||
|
||||
elif request.method == "GET":
|
||||
all_zones = route53_backend.get_all_hosted_zones()
|
||||
template = Template(LIST_HOSTED_ZONES_RESPONSE)
|
||||
return 200, headers, template.render(zones=all_zones)
|
||||
return 200, headers, template.render(zone=the_zone)
|
||||
elif request.method == "DELETE":
|
||||
route53_backend.delete_hosted_zone(zoneid)
|
||||
return 200, headers, DELETE_HOSTED_ZONE_RESPONSE
|
||||
|
||||
|
||||
def get_or_delete_hostzone_response(request, full_url, headers):
|
||||
parsed_url = urlparse(full_url)
|
||||
zoneid = parsed_url.path.rstrip('/').rsplit('/', 1)[1]
|
||||
the_zone = route53_backend.get_hosted_zone(zoneid)
|
||||
if not the_zone:
|
||||
return 404, headers, "Zone %s not Found" % zoneid
|
||||
def rrset_response(self, request, full_url, headers):
|
||||
self.setup_class(request, full_url, headers)
|
||||
|
||||
if request.method == "GET":
|
||||
template = Template(GET_HOSTED_ZONE_RESPONSE)
|
||||
parsed_url = urlparse(full_url)
|
||||
method = request.method
|
||||
|
||||
return 200, headers, template.render(zone=the_zone)
|
||||
elif request.method == "DELETE":
|
||||
route53_backend.delete_hosted_zone(zoneid)
|
||||
return 200, headers, DELETE_HOSTED_ZONE_RESPONSE
|
||||
zoneid = parsed_url.path.rstrip('/').rsplit('/', 2)[1]
|
||||
the_zone = route53_backend.get_hosted_zone(zoneid)
|
||||
if not the_zone:
|
||||
return 404, headers, "Zone %s Not Found" % zoneid
|
||||
|
||||
if method == "POST":
|
||||
elements = xmltodict.parse(self.body)
|
||||
|
||||
change_list = elements['ChangeResourceRecordSetsRequest']['ChangeBatch']['Changes']['Change']
|
||||
if not isinstance(change_list, list):
|
||||
change_list = [elements['ChangeResourceRecordSetsRequest']['ChangeBatch']['Changes']['Change']]
|
||||
|
||||
for value in change_list:
|
||||
action = value['Action']
|
||||
record_set = value['ResourceRecordSet']
|
||||
if action in ('CREATE', 'UPSERT'):
|
||||
if 'ResourceRecords' in record_set:
|
||||
resource_records = list(record_set['ResourceRecords'].values())[0]
|
||||
if not isinstance(resource_records, list):
|
||||
# Depending on how many records there are, this may or may not be a list
|
||||
resource_records = [resource_records]
|
||||
record_values = [x['Value'] for x in resource_records]
|
||||
elif 'AliasTarget' in record_set:
|
||||
record_values = [record_set['AliasTarget']['DNSName']]
|
||||
record_set['ResourceRecords'] = record_values
|
||||
if action == 'CREATE':
|
||||
the_zone.add_rrset(record_set)
|
||||
else:
|
||||
the_zone.upsert_rrset(record_set)
|
||||
elif action == "DELETE":
|
||||
if 'SetIdentifier' in record_set:
|
||||
the_zone.delete_rrset_by_id(record_set["SetIdentifier"])
|
||||
else:
|
||||
the_zone.delete_rrset_by_name(record_set["Name"])
|
||||
|
||||
return 200, headers, CHANGE_RRSET_RESPONSE
|
||||
|
||||
elif method == "GET":
|
||||
querystring = parse_qs(parsed_url.query)
|
||||
template = Template(LIST_RRSET_REPONSE)
|
||||
type_filter = querystring.get("type", [None])[0]
|
||||
name_filter = querystring.get("name", [None])[0]
|
||||
record_sets = the_zone.get_record_sets(type_filter, name_filter)
|
||||
return 200, headers, template.render(record_sets=record_sets)
|
||||
|
||||
|
||||
def rrset_response(request, full_url, headers):
|
||||
parsed_url = urlparse(full_url)
|
||||
method = request.method
|
||||
def health_check_response(self, request, full_url, headers):
|
||||
self.setup_class(request, full_url, headers)
|
||||
|
||||
zoneid = parsed_url.path.rstrip('/').rsplit('/', 2)[1]
|
||||
the_zone = route53_backend.get_hosted_zone(zoneid)
|
||||
if not the_zone:
|
||||
return 404, headers, "Zone %s Not Found" % zoneid
|
||||
parsed_url = urlparse(full_url)
|
||||
method = request.method
|
||||
|
||||
if method == "POST":
|
||||
elements = xmltodict.parse(request.body)
|
||||
if method == "POST":
|
||||
properties = xmltodict.parse(self.body)['CreateHealthCheckRequest']['HealthCheckConfig']
|
||||
health_check_args = {
|
||||
"ip_address": properties.get('IPAddress'),
|
||||
"port": properties.get('Port'),
|
||||
"type": properties['Type'],
|
||||
"resource_path": properties.get('ResourcePath'),
|
||||
"fqdn": properties.get('FullyQualifiedDomainName'),
|
||||
"search_string": properties.get('SearchString'),
|
||||
"request_interval": properties.get('RequestInterval'),
|
||||
"failure_threshold": properties.get('FailureThreshold'),
|
||||
}
|
||||
health_check = route53_backend.create_health_check(health_check_args)
|
||||
template = Template(CREATE_HEALTH_CHECK_RESPONSE)
|
||||
return 201, headers, template.render(health_check=health_check)
|
||||
elif method == "DELETE":
|
||||
health_check_id = parsed_url.path.split("/")[-1]
|
||||
route53_backend.delete_health_check(health_check_id)
|
||||
return 200, headers, DELETE_HEALTH_CHECK_REPONSE
|
||||
elif method == "GET":
|
||||
template = Template(LIST_HEALTH_CHECKS_REPONSE)
|
||||
health_checks = route53_backend.get_health_checks()
|
||||
return 200, headers, template.render(health_checks=health_checks)
|
||||
|
||||
change_list = elements['ChangeResourceRecordSetsRequest']['ChangeBatch']['Changes']['Change']
|
||||
if not isinstance(change_list, list):
|
||||
change_list = [elements['ChangeResourceRecordSetsRequest']['ChangeBatch']['Changes']['Change']]
|
||||
def not_implemented_response(self, request, full_url, headers):
|
||||
self.setup_class(request, full_url, headers)
|
||||
|
||||
for value in change_list:
|
||||
action = value['Action']
|
||||
record_set = value['ResourceRecordSet']
|
||||
if action in ('CREATE', 'UPSERT'):
|
||||
if 'ResourceRecords' in record_set:
|
||||
resource_records = list(record_set['ResourceRecords'].values())[0]
|
||||
if not isinstance(resource_records, list):
|
||||
# Depending on how many records there are, this may or may not be a list
|
||||
resource_records = [resource_records]
|
||||
record_values = [x['Value'] for x in resource_records]
|
||||
elif 'AliasTarget' in record_set:
|
||||
record_values = [record_set['AliasTarget']['DNSName']]
|
||||
record_set['ResourceRecords'] = record_values
|
||||
if action == 'CREATE':
|
||||
the_zone.add_rrset(record_set)
|
||||
else:
|
||||
the_zone.upsert_rrset(record_set)
|
||||
elif action == "DELETE":
|
||||
if 'SetIdentifier' in record_set:
|
||||
the_zone.delete_rrset_by_id(record_set["SetIdentifier"])
|
||||
else:
|
||||
the_zone.delete_rrset_by_name(record_set["Name"])
|
||||
|
||||
return 200, headers, CHANGE_RRSET_RESPONSE
|
||||
|
||||
elif method == "GET":
|
||||
querystring = parse_qs(parsed_url.query)
|
||||
template = Template(LIST_RRSET_REPONSE)
|
||||
type_filter = querystring.get("type", [None])[0]
|
||||
name_filter = querystring.get("name", [None])[0]
|
||||
record_sets = the_zone.get_record_sets(type_filter, name_filter)
|
||||
return 200, headers, template.render(record_sets=record_sets)
|
||||
action = ''
|
||||
if 'tags' in full_url:
|
||||
action = 'tags'
|
||||
elif 'trafficpolicyinstances' in full_url:
|
||||
action = 'policies'
|
||||
raise NotImplementedError("The action for {0} has not been implemented for route 53".format(action))
|
||||
|
||||
|
||||
def health_check_response(request, full_url, headers):
|
||||
parsed_url = urlparse(full_url)
|
||||
method = request.method
|
||||
def list_or_change_tags_for_resource_request(self, request, full_url, headers):
|
||||
self.setup_class(request, full_url, headers)
|
||||
|
||||
if method == "POST":
|
||||
properties = xmltodict.parse(request.body)['CreateHealthCheckRequest']['HealthCheckConfig']
|
||||
health_check_args = {
|
||||
"ip_address": properties.get('IPAddress'),
|
||||
"port": properties.get('Port'),
|
||||
"type": properties['Type'],
|
||||
"resource_path": properties.get('ResourcePath'),
|
||||
"fqdn": properties.get('FullyQualifiedDomainName'),
|
||||
"search_string": properties.get('SearchString'),
|
||||
"request_interval": properties.get('RequestInterval'),
|
||||
"failure_threshold": properties.get('FailureThreshold'),
|
||||
}
|
||||
health_check = route53_backend.create_health_check(health_check_args)
|
||||
template = Template(CREATE_HEALTH_CHECK_RESPONSE)
|
||||
return 201, headers, template.render(health_check=health_check)
|
||||
elif method == "DELETE":
|
||||
health_check_id = parsed_url.path.split("/")[-1]
|
||||
route53_backend.delete_health_check(health_check_id)
|
||||
return 200, headers, DELETE_HEALTH_CHECK_REPONSE
|
||||
elif method == "GET":
|
||||
template = Template(LIST_HEALTH_CHECKS_REPONSE)
|
||||
health_checks = route53_backend.get_health_checks()
|
||||
return 200, headers, template.render(health_checks=health_checks)
|
||||
parsed_url = urlparse(full_url)
|
||||
id_ = parsed_url.path.split("/")[-1]
|
||||
type_ = parsed_url.path.split("/")[-2]
|
||||
|
||||
def not_implemented_response(request, full_url, headers):
|
||||
action = ''
|
||||
if 'tags' in full_url:
|
||||
action = 'tags'
|
||||
elif 'trafficpolicyinstances' in full_url:
|
||||
action = 'policies'
|
||||
raise NotImplementedError("The action for {0} has not been implemented for route 53".format(action))
|
||||
if request.method == "GET":
|
||||
tags = route53_backend.list_tags_for_resource(id_)
|
||||
template = Template(LIST_TAGS_FOR_RESOURCE_RESPONSE)
|
||||
return 200, headers, template.render(
|
||||
resource_type=type_, resource_id=id_, tags=tags)
|
||||
|
||||
if request.method == "POST":
|
||||
tags = xmltodict.parse(
|
||||
self.body)['ChangeTagsForResourceRequest']
|
||||
|
||||
def list_or_change_tags_for_resource_request(request, full_url, headers):
|
||||
parsed_url = urlparse(full_url)
|
||||
id_ = parsed_url.path.split("/")[-1]
|
||||
type_ = parsed_url.path.split("/")[-2]
|
||||
if 'AddTags' in tags:
|
||||
tags = tags['AddTags']
|
||||
elif 'RemoveTagKeys' in tags:
|
||||
tags = tags['RemoveTagKeys']
|
||||
|
||||
if request.method == "GET":
|
||||
tags = route53_backend.list_tags_for_resource(id_)
|
||||
template = Template(LIST_TAGS_FOR_RESOURCE_RESPONSE)
|
||||
return 200, headers, template.render(
|
||||
resource_type=type_, resource_id=id_, tags=tags)
|
||||
route53_backend.change_tags_for_resource(id_, tags)
|
||||
template = Template(CHANGE_TAGS_FOR_RESOURCE_RESPONSE)
|
||||
|
||||
if request.method == "POST":
|
||||
tags = xmltodict.parse(
|
||||
request.body)['ChangeTagsForResourceRequest']
|
||||
|
||||
if 'AddTags' in tags:
|
||||
tags = tags['AddTags']
|
||||
elif 'RemoveTagKeys' in tags:
|
||||
tags = tags['RemoveTagKeys']
|
||||
|
||||
route53_backend.change_tags_for_resource(id_, tags)
|
||||
template = Template(CHANGE_TAGS_FOR_RESOURCE_RESPONSE)
|
||||
|
||||
return 200, headers, template.render()
|
||||
return 200, headers, template.render()
|
||||
|
||||
LIST_TAGS_FOR_RESOURCE_RESPONSE = """
|
||||
<ListTagsForResourceResponse xmlns="https://route53.amazonaws.com/doc/2015-01-01/">
|
||||
|
|
|
|||
|
|
@ -1,15 +1,25 @@
|
|||
from __future__ import unicode_literals
|
||||
from . import responses
|
||||
from .responses import Route53
|
||||
|
||||
url_bases = [
|
||||
"https://route53.amazonaws.com/201.-..-../",
|
||||
"https?://route53(.*).amazonaws.com",
|
||||
]
|
||||
|
||||
|
||||
def tag_response1(*args, **kwargs):
|
||||
return Route53().list_or_change_tags_for_resource_request(*args, **kwargs)
|
||||
|
||||
|
||||
def tag_response2(*args, **kwargs):
|
||||
return Route53().list_or_change_tags_for_resource_request(*args, **kwargs)
|
||||
|
||||
|
||||
url_paths = {
|
||||
'{0}hostedzone$': responses.list_or_create_hostzone_response,
|
||||
'{0}hostedzone/[^/]+$': responses.get_or_delete_hostzone_response,
|
||||
'{0}hostedzone/[^/]+/rrset/?$': responses.rrset_response,
|
||||
'{0}healthcheck': responses.health_check_response,
|
||||
'{0}tags/(healthcheck|hostedzone)/*': responses.list_or_change_tags_for_resource_request,
|
||||
'{0}trafficpolicyinstances/*': responses.not_implemented_response
|
||||
'{0}/(?P<api_version>[\d_-]+)/hostedzone$': Route53().list_or_create_hostzone_response,
|
||||
'{0}/(?P<api_version>[\d_-]+)/hostedzone/(?P<zone_id>[^/]+)$': Route53().get_or_delete_hostzone_response,
|
||||
'{0}/(?P<api_version>[\d_-]+)/hostedzone/(?P<zone_id>[^/]+)/rrset/?$': Route53().rrset_response,
|
||||
'{0}/(?P<api_version>[\d_-]+)/healthcheck': Route53().health_check_response,
|
||||
'{0}/(?P<api_version>[\d_-]+)/tags/healthcheck/(?P<zone_id>[^/]+)$': tag_response1,
|
||||
'{0}/(?P<api_version>[\d_-]+)/tags/hostedzone/(?P<zone_id>[^/]+)$': tag_response2,
|
||||
'{0}/(?P<api_version>[\d_-]+)/trafficpolicyinstances/*': Route53().not_implemented_response
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue