Route53 - Persist CallerReference (#3788)
This commit is contained in:
parent
5f7167ce62
commit
fdf27a70e9
@ -20,16 +20,23 @@ def create_route53_zone_id():
|
|||||||
|
|
||||||
|
|
||||||
class HealthCheck(CloudFormationModel):
|
class HealthCheck(CloudFormationModel):
|
||||||
def __init__(self, health_check_id, health_check_args):
|
def __init__(self, health_check_id, caller_reference, health_check_args):
|
||||||
self.id = health_check_id
|
self.id = health_check_id
|
||||||
self.ip_address = health_check_args.get("ip_address")
|
self.ip_address = health_check_args.get("ip_address")
|
||||||
self.port = health_check_args.get("port", 80)
|
self.port = health_check_args.get("port") or 80
|
||||||
self.type_ = health_check_args.get("type")
|
self.type_ = health_check_args.get("type")
|
||||||
self.resource_path = health_check_args.get("resource_path")
|
self.resource_path = health_check_args.get("resource_path")
|
||||||
self.fqdn = health_check_args.get("fqdn")
|
self.fqdn = health_check_args.get("fqdn")
|
||||||
self.search_string = health_check_args.get("search_string")
|
self.search_string = health_check_args.get("search_string")
|
||||||
self.request_interval = health_check_args.get("request_interval", 30)
|
self.request_interval = health_check_args.get("request_interval") or 30
|
||||||
self.failure_threshold = health_check_args.get("failure_threshold", 3)
|
self.failure_threshold = health_check_args.get("failure_threshold") or 3
|
||||||
|
self.health_threshold = health_check_args.get("health_threshold")
|
||||||
|
self.measure_latency = health_check_args.get("measure_latency") or False
|
||||||
|
self.inverted = health_check_args.get("inverted") or False
|
||||||
|
self.disabled = health_check_args.get("disabled") or False
|
||||||
|
self.enable_sni = health_check_args.get("enable_sni") or False
|
||||||
|
self.children = health_check_args.get("children") or None
|
||||||
|
self.caller_reference = caller_reference
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def physical_resource_id(self):
|
def physical_resource_id(self):
|
||||||
@ -59,25 +66,49 @@ class HealthCheck(CloudFormationModel):
|
|||||||
"request_interval": properties.get("RequestInterval"),
|
"request_interval": properties.get("RequestInterval"),
|
||||||
"failure_threshold": properties.get("FailureThreshold"),
|
"failure_threshold": properties.get("FailureThreshold"),
|
||||||
}
|
}
|
||||||
health_check = route53_backend.create_health_check(health_check_args)
|
health_check = route53_backend.create_health_check(
|
||||||
|
caller_reference=resource_name, health_check_args=health_check_args
|
||||||
|
)
|
||||||
return health_check
|
return health_check
|
||||||
|
|
||||||
def to_xml(self):
|
def to_xml(self):
|
||||||
template = Template(
|
template = Template(
|
||||||
"""<HealthCheck>
|
"""<HealthCheck>
|
||||||
<Id>{{ health_check.id }}</Id>
|
<Id>{{ health_check.id }}</Id>
|
||||||
<CallerReference>example.com 192.0.2.17</CallerReference>
|
<CallerReference>{{ health_check.caller_reference }}</CallerReference>
|
||||||
<HealthCheckConfig>
|
<HealthCheckConfig>
|
||||||
<IPAddress>{{ health_check.ip_address }}</IPAddress>
|
{% if health_check.type_ != "CALCULATED" %}
|
||||||
<Port>{{ health_check.port }}</Port>
|
<IPAddress>{{ health_check.ip_address }}</IPAddress>
|
||||||
|
<Port>{{ health_check.port }}</Port>
|
||||||
|
{% endif %}
|
||||||
<Type>{{ health_check.type_ }}</Type>
|
<Type>{{ health_check.type_ }}</Type>
|
||||||
<ResourcePath>{{ health_check.resource_path }}</ResourcePath>
|
{% if health_check.resource_path %}
|
||||||
<FullyQualifiedDomainName>{{ health_check.fqdn }}</FullyQualifiedDomainName>
|
<ResourcePath>{{ health_check.resource_path }}</ResourcePath>
|
||||||
<RequestInterval>{{ health_check.request_interval }}</RequestInterval>
|
{% endif %}
|
||||||
<FailureThreshold>{{ health_check.failure_threshold }}</FailureThreshold>
|
{% if health_check.fqdn %}
|
||||||
|
<FullyQualifiedDomainName>{{ health_check.fqdn }}</FullyQualifiedDomainName>
|
||||||
|
{% endif %}
|
||||||
|
{% if health_check.type_ != "CALCULATED" %}
|
||||||
|
<RequestInterval>{{ health_check.request_interval }}</RequestInterval>
|
||||||
|
<FailureThreshold>{{ health_check.failure_threshold }}</FailureThreshold>
|
||||||
|
<MeasureLatency>{{ health_check.measure_latency }}</MeasureLatency>
|
||||||
|
{% endif %}
|
||||||
|
{% if health_check.type_ == "CALCULATED" %}
|
||||||
|
<HealthThreshold>{{ health_check.health_threshold }}</HealthThreshold>
|
||||||
|
{% endif %}
|
||||||
|
<Inverted>{{ health_check.inverted }}</Inverted>
|
||||||
|
<Disabled>{{ health_check.disabled }}</Disabled>
|
||||||
|
<EnableSNI>{{ health_check.enable_sni }}</EnableSNI>
|
||||||
{% if health_check.search_string %}
|
{% if health_check.search_string %}
|
||||||
<SearchString>{{ health_check.search_string }}</SearchString>
|
<SearchString>{{ health_check.search_string }}</SearchString>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if health_check.children %}
|
||||||
|
<ChildHealthChecks>
|
||||||
|
{% for child in health_check.children %}
|
||||||
|
<member>{{ child }}</member>
|
||||||
|
{% endfor %}
|
||||||
|
</ChildHealthChecks>
|
||||||
|
{% endif %}
|
||||||
</HealthCheckConfig>
|
</HealthCheckConfig>
|
||||||
<HealthCheckVersion>1</HealthCheckVersion>
|
<HealthCheckVersion>1</HealthCheckVersion>
|
||||||
</HealthCheck>"""
|
</HealthCheck>"""
|
||||||
@ -390,9 +421,9 @@ class Route53Backend(BaseBackend):
|
|||||||
def delete_hosted_zone(self, id_):
|
def delete_hosted_zone(self, id_):
|
||||||
return self.zones.pop(id_.replace("/hostedzone/", ""), None)
|
return self.zones.pop(id_.replace("/hostedzone/", ""), None)
|
||||||
|
|
||||||
def create_health_check(self, health_check_args):
|
def create_health_check(self, caller_reference, health_check_args):
|
||||||
health_check_id = str(uuid.uuid4())
|
health_check_id = str(uuid.uuid4())
|
||||||
health_check = HealthCheck(health_check_id, health_check_args)
|
health_check = HealthCheck(health_check_id, caller_reference, health_check_args)
|
||||||
self.health_checks[health_check_id] = health_check
|
self.health_checks[health_check_id] = health_check
|
||||||
return health_check
|
return health_check
|
||||||
|
|
||||||
|
@ -182,20 +182,28 @@ class Route53(BaseResponse):
|
|||||||
method = request.method
|
method = request.method
|
||||||
|
|
||||||
if method == "POST":
|
if method == "POST":
|
||||||
properties = xmltodict.parse(self.body)["CreateHealthCheckRequest"][
|
json_body = xmltodict.parse(self.body)["CreateHealthCheckRequest"]
|
||||||
"HealthCheckConfig"
|
caller_reference = json_body["CallerReference"]
|
||||||
]
|
config = json_body["HealthCheckConfig"]
|
||||||
health_check_args = {
|
health_check_args = {
|
||||||
"ip_address": properties.get("IPAddress"),
|
"ip_address": config.get("IPAddress"),
|
||||||
"port": properties.get("Port"),
|
"port": config.get("Port"),
|
||||||
"type": properties["Type"],
|
"type": config["Type"],
|
||||||
"resource_path": properties.get("ResourcePath"),
|
"resource_path": config.get("ResourcePath"),
|
||||||
"fqdn": properties.get("FullyQualifiedDomainName"),
|
"fqdn": config.get("FullyQualifiedDomainName"),
|
||||||
"search_string": properties.get("SearchString"),
|
"search_string": config.get("SearchString"),
|
||||||
"request_interval": properties.get("RequestInterval"),
|
"request_interval": config.get("RequestInterval"),
|
||||||
"failure_threshold": properties.get("FailureThreshold"),
|
"failure_threshold": config.get("FailureThreshold"),
|
||||||
|
"health_threshold": config.get("HealthThreshold"),
|
||||||
|
"measure_latency": config.get("MeasureLatency"),
|
||||||
|
"inverted": config.get("Inverted"),
|
||||||
|
"disabled": config.get("Disabled"),
|
||||||
|
"enable_sni": config.get("EnableSNI"),
|
||||||
|
"children": config.get("ChildHealthChecks", {}).get("ChildHealthCheck"),
|
||||||
}
|
}
|
||||||
health_check = route53_backend.create_health_check(health_check_args)
|
health_check = route53_backend.create_health_check(
|
||||||
|
caller_reference, health_check_args
|
||||||
|
)
|
||||||
template = Template(CREATE_HEALTH_CHECK_RESPONSE)
|
template = Template(CREATE_HEALTH_CHECK_RESPONSE)
|
||||||
return 201, headers, template.render(health_check=health_check)
|
return 201, headers, template.render(health_check=health_check)
|
||||||
elif method == "DELETE":
|
elif method == "DELETE":
|
||||||
|
169
tests/test_route53/test_route53_boto3.py
Normal file
169
tests/test_route53/test_route53_boto3.py
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
import boto3
|
||||||
|
import sure # noqa
|
||||||
|
from moto import mock_route53
|
||||||
|
|
||||||
|
|
||||||
|
@mock_route53
|
||||||
|
def test_create_health_check():
|
||||||
|
client = boto3.client("route53", region_name="us-east-1")
|
||||||
|
|
||||||
|
response = client.create_health_check(
|
||||||
|
CallerReference="test-route53-health-HealthCheck-asdf",
|
||||||
|
HealthCheckConfig={
|
||||||
|
"IPAddress": "93.184.216.34",
|
||||||
|
"Port": 80,
|
||||||
|
"Type": "HTTP",
|
||||||
|
"ResourcePath": "/",
|
||||||
|
"FullyQualifiedDomainName": "example.com",
|
||||||
|
"RequestInterval": 10,
|
||||||
|
"FailureThreshold": 2,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(201)
|
||||||
|
#
|
||||||
|
check = response["HealthCheck"]
|
||||||
|
check.should.have.key("Id")
|
||||||
|
check.should.have.key("CallerReference").being.equal(
|
||||||
|
"test-route53-health-HealthCheck-asdf"
|
||||||
|
)
|
||||||
|
check.should.have.key("HealthCheckConfig")
|
||||||
|
#
|
||||||
|
config = check["HealthCheckConfig"]
|
||||||
|
config.should.have.key("IPAddress").being.equal("93.184.216.34")
|
||||||
|
config.should.have.key("Port").being.equal(80)
|
||||||
|
config.should.have.key("Type").being.equal("HTTP")
|
||||||
|
config.should.have.key("ResourcePath").being.equal("/")
|
||||||
|
config.should.have.key("FullyQualifiedDomainName").being.equal("example.com")
|
||||||
|
config.should.have.key("RequestInterval").being.equal(10)
|
||||||
|
config.should.have.key("FailureThreshold").being.equal(2)
|
||||||
|
config.should.have.key("MeasureLatency").being.equal(False)
|
||||||
|
config.should.have.key("Inverted").being.equal(False)
|
||||||
|
config.should.have.key("Disabled").being.equal(False)
|
||||||
|
config.should.have.key("EnableSNI").being.equal(False)
|
||||||
|
|
||||||
|
config.shouldnt.have.key("ChildHealthChecks")
|
||||||
|
config.shouldnt.have.key("HealthThreshold")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_route53
|
||||||
|
def test_create_health_check_with_additional_options():
|
||||||
|
client = boto3.client("route53", region_name="us-east-1")
|
||||||
|
|
||||||
|
response = client.create_health_check(
|
||||||
|
CallerReference="test-route53-health-HealthCheck-asdf",
|
||||||
|
HealthCheckConfig={
|
||||||
|
"IPAddress": "93.184.216.34",
|
||||||
|
"Port": 80,
|
||||||
|
"Type": "HTTP",
|
||||||
|
"ResourcePath": "/",
|
||||||
|
"FullyQualifiedDomainName": "example.com",
|
||||||
|
"RequestInterval": 10,
|
||||||
|
"FailureThreshold": 2,
|
||||||
|
"MeasureLatency": True,
|
||||||
|
"Inverted": True,
|
||||||
|
"Disabled": True,
|
||||||
|
"EnableSNI": True,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(201)
|
||||||
|
#
|
||||||
|
check = response["HealthCheck"]
|
||||||
|
check.should.have.key("CallerReference").being.equal(
|
||||||
|
"test-route53-health-HealthCheck-asdf"
|
||||||
|
)
|
||||||
|
check.should.have.key("HealthCheckConfig")
|
||||||
|
#
|
||||||
|
config = check["HealthCheckConfig"]
|
||||||
|
config.should.have.key("MeasureLatency").being.equal(True)
|
||||||
|
config.should.have.key("Inverted").being.equal(True)
|
||||||
|
config.should.have.key("Disabled").being.equal(True)
|
||||||
|
config.should.have.key("EnableSNI").being.equal(True)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_route53
|
||||||
|
def test_create_calculated_health_check():
|
||||||
|
client = boto3.client("route53", region_name="us-east-1")
|
||||||
|
|
||||||
|
response = client.create_health_check(
|
||||||
|
CallerReference="test-route53-health-HealthCheck-ZHV123",
|
||||||
|
HealthCheckConfig={
|
||||||
|
"Type": "CALCULATED",
|
||||||
|
"Inverted": False,
|
||||||
|
"Disabled": False,
|
||||||
|
"HealthThreshold": 1,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
check = response["HealthCheck"]
|
||||||
|
check.should.have.key("Id")
|
||||||
|
check.should.have.key("CallerReference").being.equal(
|
||||||
|
"test-route53-health-HealthCheck-ZHV123"
|
||||||
|
)
|
||||||
|
#
|
||||||
|
config = check["HealthCheckConfig"]
|
||||||
|
config.should.have.key("Type").being.equal("CALCULATED")
|
||||||
|
config.should.have.key("Inverted").being.equal(False)
|
||||||
|
config.should.have.key("Disabled").being.equal(False)
|
||||||
|
config.should.have.key("HealthThreshold").being.equal(1)
|
||||||
|
#
|
||||||
|
config.shouldnt.have.key("IPAddress")
|
||||||
|
config.shouldnt.have.key("Port")
|
||||||
|
config.shouldnt.have.key("ResourcePath")
|
||||||
|
config.shouldnt.have.key("FullyQualifiedDomainName")
|
||||||
|
config.shouldnt.have.key("RequestInterval")
|
||||||
|
config.shouldnt.have.key("FailureThreshold")
|
||||||
|
config.shouldnt.have.key("MeasureLatency")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_route53
|
||||||
|
def test_create_calculated_health_check_with_children():
|
||||||
|
client = boto3.client("route53", region_name="us-east-1")
|
||||||
|
|
||||||
|
child1 = client.create_health_check(
|
||||||
|
CallerReference="test-route53-health-HealthCheck-child1",
|
||||||
|
HealthCheckConfig={
|
||||||
|
"Type": "CALCULATED",
|
||||||
|
"Inverted": False,
|
||||||
|
"Disabled": False,
|
||||||
|
"HealthThreshold": 1,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
child2 = client.create_health_check(
|
||||||
|
CallerReference="test-route53-health-HealthCheck-child2",
|
||||||
|
HealthCheckConfig={
|
||||||
|
"Type": "CALCULATED",
|
||||||
|
"Inverted": False,
|
||||||
|
"Disabled": False,
|
||||||
|
"HealthThreshold": 1,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
parent = client.create_health_check(
|
||||||
|
CallerReference="test-route53-health-HealthCheck-parent",
|
||||||
|
HealthCheckConfig={
|
||||||
|
"Type": "CALCULATED",
|
||||||
|
"Inverted": False,
|
||||||
|
"Disabled": False,
|
||||||
|
"HealthThreshold": 1,
|
||||||
|
"ChildHealthChecks": [
|
||||||
|
child1["HealthCheck"]["Id"],
|
||||||
|
child2["HealthCheck"]["Id"],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
check = parent["HealthCheck"]
|
||||||
|
check.should.have.key("Id")
|
||||||
|
check.should.have.key("CallerReference").being.equal(
|
||||||
|
"test-route53-health-HealthCheck-parent"
|
||||||
|
)
|
||||||
|
#
|
||||||
|
config = check["HealthCheckConfig"]
|
||||||
|
config.should.have.key("Type").being.equal("CALCULATED")
|
||||||
|
config.should.have.key("Inverted").being.equal(False)
|
||||||
|
config.should.have.key("Disabled").being.equal(False)
|
||||||
|
config.should.have.key("HealthThreshold").being.equal(1)
|
||||||
|
config.should.have.key("ChildHealthChecks").being.equal(
|
||||||
|
[child1["HealthCheck"]["Id"], child2["HealthCheck"]["Id"]]
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user