Last active
September 30, 2018 10:36
Star
You must be signed in to star a gist
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import itertools | |
from collections import namedtuple | |
from boto3.session import Session | |
import colorama | |
from colorama import Fore | |
CertificateSummary = namedtuple("CertificateSummary", ["arn", "domain_name"]) | |
Certificate = namedtuple( | |
"Certificate", ["arn", "domain_name", "status", "validation_options"] | |
) | |
ValidationOption = namedtuple( | |
"DomainValidationOptions", ["validation_status", "validation_method"] | |
) | |
EnumerateResult = namedtuple("EnumerateResult", ["profile", "region", "certificates"]) | |
def list_certificates(acm): | |
def create_summary(s): | |
arn = s["CertificateArn"] | |
domain_name = s["DomainName"] | |
return CertificateSummary(arn=arn, domain_name=domain_name) | |
complete = False | |
next_token = None | |
while not complete: | |
params = dict(NextToken=next_token) if next_token else {} | |
res = acm.list_certificates(**params) | |
next_token = res.get("NextToken", None) | |
complete = next_token is None | |
for x in res["CertificateSummaryList"]: | |
yield create_summary(x) | |
def describe_certificate(acm, cert_arn): | |
def create_validation_option(o): | |
status = o["ValidationStatus"] | |
method = o["ValidationMethod"] | |
return ValidationOption(validation_status=status, validation_method=method) | |
res = acm.describe_certificate(CertificateArn=cert_arn) | |
cert = res["Certificate"] | |
options = cert.get("DomainValidationOptions", []) | |
options = [create_validation_option(x) for x in options] | |
return Certificate( | |
arn=cert_arn, | |
domain_name=cert["DomainName"], | |
validation_options=options, | |
status=cert["Status"], | |
) | |
def enumerate_certificates(profiles, regions): | |
for p, r in itertools.product(profiles, regions): | |
session = Session(profile_name=p, region_name=r) | |
acm = session.client("acm") | |
summaries = list(list_certificates(acm)) | |
certificates = [describe_certificate(acm, s.arn) for s in summaries] | |
yield EnumerateResult(profile=p, region=r, certificates=certificates) | |
def prefix_for(cert): | |
def is_issued(): | |
return cert.status == "ISSUED" | |
def has_mail_validation(): | |
return any([o.validation_method == "EMAIL" for o in cert.validation_options]) | |
if is_issued(): | |
prefix = Fore.RED + "✗" if has_mail_validation() else Fore.GREEN + "✓" | |
prefix += Fore.RESET | |
return prefix | |
else: | |
return "-" | |
def show_results(results): | |
colorama.init(autoreset=True) | |
status_width = max([ | |
len(c.status) | |
for c in itertools.chain.from_iterable([x.certificates for x in results]) | |
]) | |
for profile, profile_group in itertools.groupby(results, key=lambda x: x.profile): | |
if not profile_group: | |
continue | |
print("-" * 40) | |
print(f"[{profile}]") | |
for result in profile_group: | |
if not result.certificates: | |
continue | |
print(f"\n{result.region}") | |
for c in result.certificates: | |
prefix = prefix_for(c) | |
status = c.status.ljust(status_width) | |
methods = ",".join([o.validation_method for o in c.validation_options]) | |
print(f"{prefix} {status} {c.domain_name} ({methods})") | |
def main(): | |
profiles = ["default"] | |
regions = ["ap-northeast-1", "us-east-1"] | |
results = [r for r in enumerate_certificates(profiles, regions)] | |
show_results(results) | |
if __name__ == "__main__": | |
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[[source]] | |
url = "https://pypi.org/simple" | |
verify_ssl = true | |
name = "pypi" | |
[packages] | |
"boto3" = "*" | |
"flake8" = "*" | |
"flake8-import-order" = "*" | |
black = "*" | |
colorama = "*" | |
[dev-packages] | |
[requires] | |
python_version = "3.7" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment