Skip to content
This repository has been archived by the owner on Jan 19, 2022. It is now read-only.

Support alternative ACM domain domain validation domains #277

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions .travis.yml
Expand Up @@ -16,8 +16,8 @@ script:
- |
set -e -o pipefail;
if [ "$TRAVIS_PULL_REQUEST" != "false" ]
then git diff $TRAVIS_COMMIT_RANGE !(docs) | flake8 --diff;
else git fetch -q origin master:origin/master && git diff origin/master... !(docs) | flake8 --diff
then git diff $TRAVIS_COMMIT_RANGE !(docs) | flake8 --diff --exclude tests/cloudformation/*;
else git fetch -q origin master:origin/master && git diff origin/master... !(docs) | flake8 --diff --exclude tests/cloudformation/*
fi

# Then run the tests
Expand Down
8 changes: 7 additions & 1 deletion README.rst
Expand Up @@ -493,6 +493,9 @@ This section defines certificates for the AWS Certificate Manager. For verificat
- <alternative_name_1>
- <alternative_name_2>
validation_domain: <validation_domain> # (optional) The domain name the verfication email should go to. The default is the domain name.
domain_validation_options: # (optional) override validation_domain for specific domain names
- domain_name: <alternative_name>
validation_domain: <alternative_validation_domain>
tags:
<key>: <val> # (optional) Dictionary of keypairs to tag the resource with.

Expand All @@ -504,8 +507,11 @@ For example,
mycert:
domain: helloworld.test.dsd.io
subject_alternative_names:
- goodbye.test.dsd.io
- goodbye.test.somewhere.io
validation_domain: dsd.io
domain_validation_options:
- domain_name: goodbye.test.somewhere.io
validation_domain: somewhere.io
tags:
site: testsite

Expand Down
31 changes: 27 additions & 4 deletions bootstrap_cfn/config.py
Expand Up @@ -1329,10 +1329,33 @@ def _get_acm_certificate(self, certificate_name):
dnv = [DomainValidationOption(
DomainName=domain_name,
ValidationDomain=validation_domain)]
dnv += [DomainValidationOption(
DomainName=d,
ValidationDomain=validation_domain)
for d in acm_data.get('subject_alternative_names', [])]
# Get all subject_alternative_names and set up domain validation options
# to default to the validation_domain if there is no specific entry in
# domain_validation_options
domain_validation_options = acm_data.get('domain_validation_options', [])
validated_domains = []
for domain_validation_option in domain_validation_options:
option_domain_name = domain_validation_option.get("domain_name", None)
option_validation_domain = domain_validation_option.get("validation_domain", None)
if option_domain_name is None or option_validation_domain is None:
raise errors.CfnConfigError("domain_validation_options require domain_name and validation_domain set")
# if the domain name validation is overridden in the domain_option,
# warn
if option_domain_name == domain_name:
logging.warning("domain_validation_options overrides the "
"validation option of the main domain. Use "
"validation_domain instead.")
dnv += [DomainValidationOption(
DomainName=option_domain_name,
ValidationDomain=option_validation_domain)
]
validated_domains.append(option_domain_name)
# If the alternative name is not explicitly set a validation domain,
# use the default
for subject_alternative_name in acm_data.get('subject_alternative_names', []):
if subject_alternative_name not in validated_domains:
dnv += [DomainValidationOption(DomainName=subject_alternative_name,
ValidationDomain=validation_domain)]

certificate = Certificate(
canonical_certificate_name,
Expand Down
8 changes: 6 additions & 2 deletions tests/cloudformation/sample-project_acm.yaml
@@ -1,4 +1,5 @@
# noqa
---
dev:
ec2:
tags:
Expand Down Expand Up @@ -35,9 +36,12 @@ dev:
mycert:
domain: helloworld.test.dsd.io
subject_alternative_names:
- goodbye.test.dsd.io
- hello_again.test.dsd.io
- goodbye.test.somewhere.io
- hello_again.subdomain.dsd.io
validation_domain: dsd.io
domain_validation_options:
- domain_name: goodbye.test.somewhere.io
validation_domain: somewhere.io
tags:
test_key1: test_value_1
test_key2: test_value_2
Expand Down
37 changes: 21 additions & 16 deletions tests/test_acm.py
Expand Up @@ -35,29 +35,34 @@ def test_acm(self):
{'Key': 'test_key1', 'Value': 'test_value_1'},
{'Key': 'test_key2', 'Value': 'test_value_2'}
]
subject_alternative_names = ['goodbye.test.dsd.io', 'hello_again.test.dsd.io']
subject_alternative_names = ['goodbye.test.somewhere.io', 'hello_again.subdomain.dsd.io']

# The main domain should use validation_domain,
# 'goodbye.test.somewhere.io' should use the domain_validation_options
# to validate on somewhere.io.
# 'hello_again.subdomain.dsd.io' has no validation_options so should
# default to the validation_domain
domain_validation_options = [
DomainValidationOption(
DomainName=domain_name,
ValidationDomain=validation_domain
),
DomainValidationOption(
DomainName=subject_alternative_names[0],
ValidationDomain=validation_domain
DomainName='goodbye.test.somewhere.io',
ValidationDomain='somewhere.io'
),
DomainValidationOption(
DomainName=subject_alternative_names[1],
DomainName='hello_again.subdomain.dsd.io',
ValidationDomain=validation_domain
)
]
ACMCertificate = Certificate(
certificate_name,
DomainName=domain_name,
SubjectAlternativeNames=subject_alternative_names,
DomainValidationOptions=domain_validation_options,
Tags=tags
)
certificate_name,
DomainName=domain_name,
SubjectAlternativeNames=subject_alternative_names,
DomainValidationOptions=domain_validation_options,
Tags=tags
)
certificate_cfg = [config_parser._get_acm_certificate(certificate_name)]
expected = [ACMCertificate]
compare(self._resources_to_dict(expected),
Expand All @@ -80,12 +85,12 @@ def test_acm_non_alphanumeric(self):
ValidationDomain=domain_name
)
ACMCertificate = Certificate(
parsed_certificate_name,
DomainName=domain_name,
SubjectAlternativeNames=subject_alternative_names,
DomainValidationOptions=[domain_validation_options],
Tags=tags
)
parsed_certificate_name,
DomainName=domain_name,
SubjectAlternativeNames=subject_alternative_names,
DomainValidationOptions=[domain_validation_options],
Tags=tags
)
certificate_cfg = [config_parser._get_acm_certificate(certificate_name)]
expected = [ACMCertificate]
compare(self._resources_to_dict(expected),
Expand Down