Skip to content
Snippets Groups Projects
cert2json.py 4.17 KiB
#!/usr/bin/env python3
#
"""Certbot list 2 json

Usage:
  cert2json.py --provider <PROVIDER>
  cert2json.py (-h | --help)

Options:
  -h --help                       Show this screen
  -p PROVIDER --provider=PROVIDER Provider [sectigo_ev | sectigo_ov | letsencrypt| all]
"""
import ast
import json
import re
import os
import time
from glob import glob
import subprocess as sp
import yaml
from docopt import docopt


BASE_DIR = '/var/www/acme_web'
ARGS = docopt(__doc__)
PROVIDER = ARGS['--provider']
TIMENOW = time.strftime('%Y-%m-%d %X %Z')
TIMESTAMP_JS = """var mytimestamp = "This report was generated on {}"
document.getElementById("factstimestamp").innerHTML = mytimestamp;\n""".format(TIMENOW)
if PROVIDER not in ["letsencrypt", "sectigo_ov", "sectigo_ev", "all"]:
    print("valid providers are: sectigo_ev, sectigo_ov and letsencrypt")
    os.sys.exit()
elif PROVIDER == 'all':
    PROVIDERS = ["letsencrypt", "sectigo_ov", "sectigo_ev"]
else:
    PROVIDERS = [PROVIDER]


if __name__ == "__main__":

    for acme_provider in PROVIDERS:
        cmd = '/usr/local/bin/certbot certificates -c /etc/{}/cli.ini'.format(
            acme_provider).split()
        cbot_child = sp.Popen(cmd, stdout=sp.PIPE, stderr=sp.PIPE)
        cbot_out, _ = cbot_child.communicate()
        decoded_output = cbot_out.decode("utf-8").split("\n")

        provider_dir = os.path.join(BASE_DIR, acme_provider)
        yaml_file = "{}/{}.yaml".format(provider_dir, acme_provider)
        json_file = "{}/{}.json".format(provider_dir, acme_provider)
        json_expired = "{}/{}_expired.json".format(provider_dir, acme_provider)
        os.chmod(provider_dir, 0o755)

        # open yaml for writing
        with open(yaml_file, "w") as yaml_out:
            yaml_out.write("---\n")
            for txt_line in decoded_output:
                if "Certificate Name:" in txt_line:
                    txt_line_out = re.sub('.*Certificate Name: ', '- certname: ', txt_line)
                elif "Serial Number: " in txt_line:
                    txt_line_out = re.sub('.*Serial Number: ', '  serial_number: ', txt_line)
                elif "Domains: " in txt_line:
                    domains = re.sub('.*Domains: ', '', txt_line).split(" ")
                    domains_modified = ['"' + i + '"' for i in domains]
                    domains_joined = '\n    - '.join(domains_modified)
                    txt_line_out = "  domains:\n    - " + domains_joined
                elif "Expiry Date: " in txt_line:
                    txt_line_out = re.sub('.*Expiry Date: .*\(', '  expiry_date: "', txt_line) #pylint: disable=W1401
                    txt_line_out = txt_line_out.replace(')', '') + '"'
                else:
                    txt_line_out = None

                if txt_line_out:
                    yaml_out.write("{}\n".format(txt_line_out))

        yaml_out.close()

        # open yaml for reading and json(s) for writing
        with open(yaml_file, 'r') as yaml_in, \
        open(json_file, "w") as json_out, \
        open(json_expired, "w") as json_exp_out:
            yaml_object = yaml.safe_load(yaml_in)
            json_dumped = json.dumps(yaml_object, indent=4)
            # sorting list of dictionaries by value: https://stackoverflow.com/a/73050/3151187
            sorted_certname = sorted(ast.literal_eval(json_dumped), key=lambda k: k['certname'])
            sorted_expired = sorted(ast.literal_eval(json_dumped), key=lambda k: k['expiry_date'])
            sorted_certname_json = json.dumps(sorted_certname, indent=4)
            sorted_expired_json = json.dumps(sorted_expired, indent=4)
            json_out.write(sorted_certname_json)
            json_exp_out.write(sorted_expired_json)

        # write timestamp
        with open('{}/timestamp.js'.format(provider_dir), 'w') as timestamp_file:
            timestamp_file.write(TIMESTAMP_JS)

        timestamp_file.close()
        json_out.close()
        json_exp_out.close()
        #os.unlink(yaml_file)

    # fix permissions
    os.chmod(BASE_DIR, 0o755)
    WEB_FILES = glob('{}/*'.format(BASE_DIR)) + glob('{}/*/*'.format(BASE_DIR))
    for www_file in WEB_FILES:
        if os.path.isdir(www_file):
            os.chmod(www_file, 0o755)
        else:
            os.chmod(www_file, 0o644)