Route53: change_resource_record_sets(): Relax DELETE validation (#7153)
This commit is contained in:
parent
9098554903
commit
dc18556449
@ -11,7 +11,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
service: ["acm"]
|
||||
service: ["acm", "route53"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@ -30,4 +30,7 @@ jobs:
|
||||
- name: Run tests
|
||||
run: |
|
||||
mkdir ~/.aws && touch ~/.aws/credentials && echo -e "[default]\naws_access_key_id = test\naws_secret_access_key = test" > ~/.aws/credentials
|
||||
cd other_langs/terraform/${{ matrix.service }} && terraform init && terraform apply --auto-approve
|
||||
cd other_langs/terraform/${{ matrix.service }}
|
||||
terraform init
|
||||
terraform apply --auto-approve
|
||||
terraform apply -destroy --auto-approve
|
||||
|
@ -314,6 +314,27 @@ class ChangeList(List[Dict[str, Any]]):
|
||||
item["ResourceRecordSet"]["Name"] = item["ResourceRecordSet"]["Name"].strip(".")
|
||||
return super().__contains__(item)
|
||||
|
||||
def has_insert_or_update(self, new_rr_set: Dict[str, Any]) -> bool:
|
||||
"""
|
||||
Check if a CREATE or UPSERT record exists where the name and type is the same as the provided record
|
||||
If the existing record has TTL/ResourceRecords, the new TTL should have the same
|
||||
"""
|
||||
for change in self:
|
||||
if change["Action"] in ["CREATE", "UPSERT"]:
|
||||
rr_set = change["ResourceRecordSet"]
|
||||
if (
|
||||
rr_set["Name"] == new_rr_set["Name"].strip(".")
|
||||
and rr_set["Type"] == new_rr_set["Type"]
|
||||
):
|
||||
if "TTL" in rr_set:
|
||||
if rr_set["TTL"] == new_rr_set.get("TTL") and rr_set[
|
||||
"ResourceRecords"
|
||||
] == new_rr_set.get("ResourceRecords"):
|
||||
return True
|
||||
else:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class FakeZone(CloudFormationModel):
|
||||
def __init__(
|
||||
@ -632,13 +653,8 @@ class Route53Backend(BaseBackend):
|
||||
for value in change_list:
|
||||
if value["Action"] == "DELETE":
|
||||
# To delete a resource record set, you must specify all the same values that you specified when you created it.
|
||||
corresponding_create = copy.deepcopy(value)
|
||||
corresponding_create["Action"] = "CREATE"
|
||||
corresponding_upsert = copy.deepcopy(value)
|
||||
corresponding_upsert["Action"] = "UPSERT"
|
||||
if (
|
||||
corresponding_create not in the_zone.rr_changes
|
||||
and corresponding_upsert not in the_zone.rr_changes
|
||||
if not the_zone.rr_changes.has_insert_or_update(
|
||||
value["ResourceRecordSet"]
|
||||
):
|
||||
msg = f"Invalid request: Expected exactly one of [AliasTarget, all of [TTL, and ResourceRecords], or TrafficPolicyInstanceId], but found none in Change with [Action=DELETE, Name={value['ResourceRecordSet']['Name']}, Type={value['ResourceRecordSet']['Type']}, SetIdentifier={value['ResourceRecordSet'].get('SetIdentifier', 'null')}]"
|
||||
raise InvalidInput(msg)
|
||||
|
14
other_langs/terraform/route53/providers.tf
Normal file
14
other_langs/terraform/route53/providers.tf
Normal file
@ -0,0 +1,14 @@
|
||||
provider "aws" {
|
||||
region = "us-east-1"
|
||||
s3_use_path_style = true
|
||||
skip_credentials_validation = true
|
||||
skip_metadata_api_check = true
|
||||
skip_requesting_account_id = true
|
||||
|
||||
endpoints {
|
||||
route53 = "http://localhost:5000"
|
||||
}
|
||||
|
||||
access_key = "my-access-key"
|
||||
secret_key = "my-secret-key"
|
||||
}
|
13
other_langs/terraform/route53/route53.tf
Normal file
13
other_langs/terraform/route53/route53.tf
Normal file
@ -0,0 +1,13 @@
|
||||
resource "aws_route53_zone" "test" {
|
||||
name = "test.co"
|
||||
}
|
||||
|
||||
resource "aws_route53_record" "svc_healtchecked_a_record" {
|
||||
zone_id = aws_route53_zone.test.id
|
||||
name = "svc-healthchecked.${aws_route53_zone.test.name}"
|
||||
type = "A"
|
||||
ttl = 60
|
||||
set_identifier = "repl-0"
|
||||
multivalue_answer_routing_policy = true
|
||||
records = ["172.31.0.100", "172.31.0.101"]
|
||||
}
|
@ -729,7 +729,10 @@ def test_change_resource_record_sets_crud_valid():
|
||||
|
||||
|
||||
@mock_route53
|
||||
def test_change_resource_record_sets_crud_valid_with_special_xml_chars():
|
||||
@pytest.mark.parametrize("multi_value_answer", [True, False, None])
|
||||
def test_change_resource_record_sets_crud_valid_with_special_xml_chars(
|
||||
multi_value_answer,
|
||||
):
|
||||
conn = boto3.client("route53", region_name="us-east-1")
|
||||
conn.create_hosted_zone(
|
||||
Name="db.",
|
||||
@ -757,6 +760,10 @@ def test_change_resource_record_sets_crud_valid_with_special_xml_chars():
|
||||
}
|
||||
],
|
||||
}
|
||||
if multi_value_answer is not None:
|
||||
txt_record_endpoint_payload["Changes"][0]["ResourceRecordSet"][
|
||||
"MultiValueAnswer"
|
||||
] = multi_value_answer
|
||||
conn.change_resource_record_sets(
|
||||
HostedZoneId=hosted_zone_id, ChangeBatch=txt_record_endpoint_payload
|
||||
)
|
||||
@ -784,6 +791,10 @@ def test_change_resource_record_sets_crud_valid_with_special_xml_chars():
|
||||
}
|
||||
],
|
||||
}
|
||||
if multi_value_answer is not None:
|
||||
txt_record_with_special_char_endpoint_payload["Changes"][0][
|
||||
"ResourceRecordSet"
|
||||
]["MultiValueAnswer"] = multi_value_answer
|
||||
conn.change_resource_record_sets(
|
||||
HostedZoneId=hosted_zone_id,
|
||||
ChangeBatch=txt_record_with_special_char_endpoint_payload,
|
||||
@ -830,7 +841,7 @@ def test_change_resource_record_set__delete_should_match_create():
|
||||
"HostedZone"
|
||||
]["Id"]
|
||||
|
||||
create_call = client.change_resource_record_sets(
|
||||
client.change_resource_record_sets(
|
||||
HostedZoneId=hosted_zone_id,
|
||||
ChangeBatch={
|
||||
"Changes": [
|
||||
@ -846,8 +857,6 @@ def test_change_resource_record_set__delete_should_match_create():
|
||||
]
|
||||
},
|
||||
)
|
||||
waiter = client.get_waiter("resource_record_sets_changed")
|
||||
waiter.wait(Id=create_call["ChangeInfo"]["Id"])
|
||||
|
||||
with pytest.raises(ClientError) as exc:
|
||||
client.change_resource_record_sets(
|
||||
|
Loading…
Reference in New Issue
Block a user