Skip to content

Instantly share code, notes, and snippets.

@yoshihitoh
Last active September 30, 2018 10:36
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save yoshihitoh/21f54a39d8ee0cf950f464899e109cbd to your computer and use it in GitHub Desktop.
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()
[[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