Skip to content

Commit

Permalink
ACM: DomainValidationOptions should be the same for validated certifi…
Browse files Browse the repository at this point in the history
…cates (#7233)
  • Loading branch information
bblommers authored Jan 19, 2024
1 parent e379afe commit 5de7d4d
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 20 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/tests_terraform_examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,9 @@ jobs:
cd other_langs/terraform/${{ matrix.service }}
terraform init
terraform apply --auto-approve
echo "Verify nothing changes when ACM certificates are validated"
sleep 30
terraform plan -detailed-exitcode
sleep 30
terraform plan -detailed-exitcode
terraform apply -destroy --auto-approve
32 changes: 15 additions & 17 deletions moto/acm/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,24 +343,22 @@ def describe(self) -> Dict[str, Any]:
domain_names = set(sans + [self.common_name])
validation_options = []

if self.status == "PENDING_VALIDATION":
for san in domain_names:
resource_record = {
"Name": f"_d930b28be6c5927595552b219965053e.{san}.",
"Type": "CNAME",
"Value": "_c9edd76ee4a0e2a74388032f3861cc50.ykybfrwcxw.acm-validations.aws.",
for san in domain_names:
resource_record = {
"Name": f"_d930b28be6c5927595552b219965053e.{san}.",
"Type": "CNAME",
"Value": "_c9edd76ee4a0e2a74388032f3861cc50.ykybfrwcxw.acm-validations.aws.",
}
validation_options.append(
{
"DomainName": san,
"ValidationDomain": san,
"ValidationStatus": self.status,
"ValidationMethod": "DNS",
"ResourceRecord": resource_record,
}
validation_options.append(
{
"DomainName": san,
"ValidationDomain": san,
"ValidationStatus": self.status,
"ValidationMethod": "DNS",
"ResourceRecord": resource_record,
}
)
else:
validation_options = [{"DomainName": name} for name in domain_names]
)

result["Certificate"]["DomainValidationOptions"] = validation_options

if self.type == "IMPORTED":
Expand Down
1 change: 1 addition & 0 deletions moto/route53/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ def __init__(self, kwargs: Dict[str, Any]):
self.alias_target = kwargs.get("AliasTarget", [])
self.failover = kwargs.get("Failover", [])
self.geo_location = kwargs.get("GeoLocation", [])
self.multi_value = kwargs.get("MultiValueAnswer")

@staticmethod
def cloudformation_name_type() -> str:
Expand Down
3 changes: 3 additions & 0 deletions moto/route53/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,9 @@ def reusable_delegation_set(self, request: Any, full_url: str, headers: Any) ->
{% if record.failover %}
<Failover>{{ record.failover }}</Failover>
{% endif %}
{% if record.multi_value %}
<MultiValueAnswer>{{ record.multi_value }}</MultiValueAnswer>
{% endif %}
{% if record.geo_location %}
<GeoLocation>
{% for geo_key in ['ContinentCode','CountryCode','SubdivisionCode'] %}
Expand Down
18 changes: 15 additions & 3 deletions tests/test_acm/test_acm.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import uuid
from time import sleep
from unittest import SkipTest, mock

import boto3
Expand Down Expand Up @@ -180,7 +181,6 @@ def test_describe_certificate():
assert len(resp["Certificate"]["DomainValidationOptions"]) == 1
validation_option = resp["Certificate"]["DomainValidationOptions"][0]
assert validation_option["DomainName"] == SERVER_COMMON_NAME
assert "ValidationDomain" not in validation_option


@mock_acm
Expand Down Expand Up @@ -388,7 +388,10 @@ def test_request_certificate():


@mock_acm
@mock.patch("moto.settings.ACM_VALIDATION_WAIT", 1)
def test_request_certificate_with_optional_arguments():
if not settings.TEST_DECORATOR_MODE:
raise SkipTest("Can only change setting in DecoratorMode")
client = boto3.client("acm", region_name="eu-central-1")

token = str(uuid.uuid4())
Expand All @@ -406,12 +409,21 @@ def test_request_certificate_with_optional_arguments():
arn_1 = resp["CertificateArn"]

cert = client.describe_certificate(CertificateArn=arn_1)["Certificate"]
assert cert["Status"] == "PENDING_VALIDATION"
assert len(cert["SubjectAlternativeNames"]) == 3
assert len(cert["DomainValidationOptions"]) == 3
assert {option["DomainName"] for option in cert["DomainValidationOptions"]} == set(
validation_options = cert["DomainValidationOptions"].copy()
assert len(validation_options) == 3
assert {option["DomainName"] for option in validation_options} == set(
cert["SubjectAlternativeNames"]
)

# Verify SAN's are still the same, even after the Certificate is validated
sleep(2)
for opt in validation_options:
opt["ValidationStatus"] = "ISSUED"
cert = client.describe_certificate(CertificateArn=arn_1)["Certificate"]
assert cert["DomainValidationOptions"] == validation_options

resp = client.list_tags_for_certificate(CertificateArn=arn_1)
tags = {item["Key"]: item.get("Value", "__NONE__") for item in resp["Tags"]}
assert len(tags) == 2
Expand Down
1 change: 1 addition & 0 deletions tests/test_route53/test_route53.py
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,7 @@ def test_change_resource_record_sets_crud_valid_with_special_xml_chars(
assert cname_record_detail["ResourceRecords"] == [
{"Value": "SomeInitialValue&NewValue"}
]
assert cname_record_detail.get("MultiValueAnswer") == multi_value_answer

# Delete record.
delete_payload = {
Expand Down

0 comments on commit 5de7d4d

Please sign in to comment.