ACM: describe_certificate() should return a DomainValidationOption for each SAN (#7144)
This commit is contained in:
parent
34a0c20d03
commit
0bbe1f1717
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -82,6 +82,10 @@ jobs:
|
|||||||
needs: lint
|
needs: lint
|
||||||
uses: ./.github/workflows/tests_sdk_ruby.yml
|
uses: ./.github/workflows/tests_sdk_ruby.yml
|
||||||
|
|
||||||
|
terraformexamplestest:
|
||||||
|
needs: lint
|
||||||
|
uses: ./.github/workflows/tests_terraform_examples.yml
|
||||||
|
|
||||||
test:
|
test:
|
||||||
needs: [lint]
|
needs: [lint]
|
||||||
if: "!contains(github.event.pull_request.labels.*.name, 'java')"
|
if: "!contains(github.event.pull_request.labels.*.name, 'java')"
|
||||||
|
33
.github/workflows/tests_terraform_examples.yml
vendored
Normal file
33
.github/workflows/tests_terraform_examples.yml
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# Small, self contained Terraform examples
|
||||||
|
# Scripts should be placed in:
|
||||||
|
# other_langs/terraform/service
|
||||||
|
|
||||||
|
name: Terraform Examples
|
||||||
|
on: [workflow_call]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
service: ["acm"]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: Set up Python 3.8
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: "3.8"
|
||||||
|
- name: Start MotoServer
|
||||||
|
run: |
|
||||||
|
pip install build
|
||||||
|
python -m build
|
||||||
|
docker run --rm -t --name motoserver -e TEST_SERVER_MODE=true -e AWS_SECRET_ACCESS_KEY=server_secret -e AWS_ACCESS_KEY_ID=server_key -v `pwd`:/moto -p 5000:5000 -v /var/run/docker.sock:/var/run/docker.sock python:3.10-slim /moto/scripts/ci_moto_server.sh &
|
||||||
|
python scripts/ci_wait_for_server.py
|
||||||
|
- 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
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -37,3 +37,5 @@ other_langs/tests_java/target
|
|||||||
other_langs/tests_dotnet/ExampleTestProject/bin
|
other_langs/tests_dotnet/ExampleTestProject/bin
|
||||||
other_langs/tests_dotnet/ExampleTestProject/obj
|
other_langs/tests_dotnet/ExampleTestProject/obj
|
||||||
other_langs/tests_ruby/Gemfile.lock
|
other_langs/tests_ruby/Gemfile.lock
|
||||||
|
other_langs/terraform/*/.terraform*
|
||||||
|
other_langs/terraform/*/terraform*
|
||||||
|
@ -337,25 +337,32 @@ class CertBundle(BaseModel):
|
|||||||
"ExtendedKeyUsages": [],
|
"ExtendedKeyUsages": [],
|
||||||
"RenewalEligibility": "INELIGIBLE",
|
"RenewalEligibility": "INELIGIBLE",
|
||||||
"Options": {"CertificateTransparencyLoggingPreference": "ENABLED"},
|
"Options": {"CertificateTransparencyLoggingPreference": "ENABLED"},
|
||||||
"DomainValidationOptions": [{"DomainName": self.common_name}],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
domain_names = set(sans + [self.common_name])
|
||||||
|
validation_options = []
|
||||||
|
|
||||||
if self.status == "PENDING_VALIDATION":
|
if self.status == "PENDING_VALIDATION":
|
||||||
result["Certificate"]["DomainValidationOptions"][0][
|
for san in domain_names:
|
||||||
"ValidationDomain"
|
resource_record = {
|
||||||
] = self.common_name
|
"Name": f"_d930b28be6c5927595552b219965053e.{san}.",
|
||||||
result["Certificate"]["DomainValidationOptions"][0][
|
"Type": "CNAME",
|
||||||
"ValidationStatus"
|
"Value": "_c9edd76ee4a0e2a74388032f3861cc50.ykybfrwcxw.acm-validations.aws.",
|
||||||
] = self.status
|
}
|
||||||
result["Certificate"]["DomainValidationOptions"][0]["ResourceRecord"] = {
|
validation_options.append(
|
||||||
"Name": f"_d930b28be6c5927595552b219965053e.{self.common_name}.",
|
{
|
||||||
"Type": "CNAME",
|
"DomainName": san,
|
||||||
"Value": "_c9edd76ee4a0e2a74388032f3861cc50.ykybfrwcxw.acm-validations.aws.",
|
"ValidationDomain": san,
|
||||||
}
|
"ValidationStatus": self.status,
|
||||||
result["Certificate"]["DomainValidationOptions"][0][
|
"ValidationMethod": "DNS",
|
||||||
"ValidationMethod"
|
"ResourceRecord": resource_record,
|
||||||
] = "DNS"
|
}
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
validation_options = [{"DomainName": name} for name in domain_names]
|
||||||
|
result["Certificate"]["DomainValidationOptions"] = validation_options
|
||||||
|
|
||||||
if self.type == "IMPORTED":
|
if self.type == "IMPORTED":
|
||||||
result["Certificate"]["ImportedAt"] = datetime_to_epoch(self.created_at)
|
result["Certificate"]["ImportedAt"] = datetime_to_epoch(self.created_at)
|
||||||
else:
|
else:
|
||||||
|
42
other_langs/terraform/acm/acm.tf
Normal file
42
other_langs/terraform/acm/acm.tf
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
locals {
|
||||||
|
domain_name = "test.co"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_route53_zone" "test" {
|
||||||
|
name = local.domain_name
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_acm_certificate" "certificate" {
|
||||||
|
domain_name = local.domain_name
|
||||||
|
validation_method = "DNS"
|
||||||
|
|
||||||
|
subject_alternative_names = ["*.${local.domain_name}"]
|
||||||
|
|
||||||
|
lifecycle {
|
||||||
|
create_before_destroy = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_route53_record" "certificate_validation" {
|
||||||
|
for_each = {
|
||||||
|
for dvo in aws_acm_certificate.certificate.domain_validation_options : dvo.domain_name => {
|
||||||
|
name = dvo.resource_record_name
|
||||||
|
record = dvo.resource_record_value
|
||||||
|
type = dvo.resource_record_type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allow_overwrite = true
|
||||||
|
name = each.value.name
|
||||||
|
records = [each.value.record]
|
||||||
|
ttl = 60
|
||||||
|
type = each.value.type
|
||||||
|
zone_id = aws_route53_zone.test.zone_id
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_acm_certificate_validation" "validation" {
|
||||||
|
certificate_arn = aws_acm_certificate.certificate.arn
|
||||||
|
validation_record_fqdns = [
|
||||||
|
for record in aws_route53_record.certificate_validation : record.fqdn
|
||||||
|
]
|
||||||
|
}
|
15
other_langs/terraform/acm/providers.tf
Normal file
15
other_langs/terraform/acm/providers.tf
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
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 {
|
||||||
|
acm = "http://localhost:5000"
|
||||||
|
route53 = "http://localhost:5000"
|
||||||
|
}
|
||||||
|
|
||||||
|
access_key = "my-access-key"
|
||||||
|
secret_key = "my-secret-key"
|
||||||
|
}
|
@ -385,7 +385,7 @@ def test_request_certificate():
|
|||||||
|
|
||||||
|
|
||||||
@mock_acm
|
@mock_acm
|
||||||
def test_request_certificate_with_tags():
|
def test_request_certificate_with_optional_arguments():
|
||||||
client = boto3.client("acm", region_name="eu-central-1")
|
client = boto3.client("acm", region_name="eu-central-1")
|
||||||
|
|
||||||
token = str(uuid.uuid4())
|
token = str(uuid.uuid4())
|
||||||
@ -402,6 +402,13 @@ def test_request_certificate_with_tags():
|
|||||||
assert "CertificateArn" in resp
|
assert "CertificateArn" in resp
|
||||||
arn_1 = resp["CertificateArn"]
|
arn_1 = resp["CertificateArn"]
|
||||||
|
|
||||||
|
cert = client.describe_certificate(CertificateArn=arn_1)["Certificate"]
|
||||||
|
assert len(cert["SubjectAlternativeNames"]) == 3
|
||||||
|
assert len(cert["DomainValidationOptions"]) == 3
|
||||||
|
assert {option["DomainName"] for option in cert["DomainValidationOptions"]} == set(
|
||||||
|
cert["SubjectAlternativeNames"]
|
||||||
|
)
|
||||||
|
|
||||||
resp = client.list_tags_for_certificate(CertificateArn=arn_1)
|
resp = client.list_tags_for_certificate(CertificateArn=arn_1)
|
||||||
tags = {item["Key"]: item.get("Value", "__NONE__") for item in resp["Tags"]}
|
tags = {item["Key"]: item.get("Value", "__NONE__") for item in resp["Tags"]}
|
||||||
assert len(tags) == 2
|
assert len(tags) == 2
|
||||||
|
Loading…
Reference in New Issue
Block a user