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
 | 
			
		||||
    uses: ./.github/workflows/tests_sdk_ruby.yml
 | 
			
		||||
 | 
			
		||||
  terraformexamplestest:
 | 
			
		||||
    needs: lint
 | 
			
		||||
    uses: ./.github/workflows/tests_terraform_examples.yml
 | 
			
		||||
 | 
			
		||||
  test:
 | 
			
		||||
    needs: [lint]
 | 
			
		||||
    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/obj
 | 
			
		||||
other_langs/tests_ruby/Gemfile.lock
 | 
			
		||||
other_langs/terraform/*/.terraform*
 | 
			
		||||
other_langs/terraform/*/terraform*
 | 
			
		||||
 | 
			
		||||
@ -337,25 +337,32 @@ class CertBundle(BaseModel):
 | 
			
		||||
                "ExtendedKeyUsages": [],
 | 
			
		||||
                "RenewalEligibility": "INELIGIBLE",
 | 
			
		||||
                "Options": {"CertificateTransparencyLoggingPreference": "ENABLED"},
 | 
			
		||||
                "DomainValidationOptions": [{"DomainName": self.common_name}],
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        domain_names = set(sans + [self.common_name])
 | 
			
		||||
        validation_options = []
 | 
			
		||||
 | 
			
		||||
        if self.status == "PENDING_VALIDATION":
 | 
			
		||||
            result["Certificate"]["DomainValidationOptions"][0][
 | 
			
		||||
                "ValidationDomain"
 | 
			
		||||
            ] = self.common_name
 | 
			
		||||
            result["Certificate"]["DomainValidationOptions"][0][
 | 
			
		||||
                "ValidationStatus"
 | 
			
		||||
            ] = self.status
 | 
			
		||||
            result["Certificate"]["DomainValidationOptions"][0]["ResourceRecord"] = {
 | 
			
		||||
                "Name": f"_d930b28be6c5927595552b219965053e.{self.common_name}.",
 | 
			
		||||
            for san in domain_names:
 | 
			
		||||
                resource_record = {
 | 
			
		||||
                    "Name": f"_d930b28be6c5927595552b219965053e.{san}.",
 | 
			
		||||
                    "Type": "CNAME",
 | 
			
		||||
                    "Value": "_c9edd76ee4a0e2a74388032f3861cc50.ykybfrwcxw.acm-validations.aws.",
 | 
			
		||||
                }
 | 
			
		||||
            result["Certificate"]["DomainValidationOptions"][0][
 | 
			
		||||
                "ValidationMethod"
 | 
			
		||||
            ] = "DNS"
 | 
			
		||||
                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":
 | 
			
		||||
            result["Certificate"]["ImportedAt"] = datetime_to_epoch(self.created_at)
 | 
			
		||||
        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
 | 
			
		||||
def test_request_certificate_with_tags():
 | 
			
		||||
def test_request_certificate_with_optional_arguments():
 | 
			
		||||
    client = boto3.client("acm", region_name="eu-central-1")
 | 
			
		||||
 | 
			
		||||
    token = str(uuid.uuid4())
 | 
			
		||||
@ -402,6 +402,13 @@ def test_request_certificate_with_tags():
 | 
			
		||||
    assert "CertificateArn" in resp
 | 
			
		||||
    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)
 | 
			
		||||
    tags = {item["Key"]: item.get("Value", "__NONE__") for item in resp["Tags"]}
 | 
			
		||||
    assert len(tags) == 2
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user