diff --git a/rsconf/component/__init__.py b/rsconf/component/__init__.py index ef51dcef..fa18e611 100644 --- a/rsconf/component/__init__.py +++ b/rsconf/component/__init__.py @@ -626,7 +626,7 @@ def _find_tls_crt(j2_ctx, domain): ): src = d.join(s) # due to dots in domain, we can't use ext= - if (src + tls.KEY_EXT).check(): + if (src + tls.CRT_EXT).check(): return src, domain assert j2_ctx.component.tls_crt_create, f"{domain}: tls crt for domain not found" src = d.join(domain) diff --git a/rsconf/pkcli/tls.py b/rsconf/pkcli/tls.py index 07f8f503..caf37393 100644 --- a/rsconf/pkcli/tls.py +++ b/rsconf/pkcli/tls.py @@ -7,6 +7,7 @@ from pykern import pkcompat from pykern import pkconfig from pykern import pkio +from pykern import pkyaml from pykern.pkcollections import PKDict from pykern.pkdebug import pkdc, pkdp, pkdlog, pkdformat import cryptography.x509 @@ -42,6 +43,19 @@ def check_expiring(authority_urn_re=None): return tuple(e.path.purebasename for e in _expiring(authority_urn_re)) or None +def db_yaml(path): + """Generate yml from all certs in tls_d + + Args: + path (str): where to write yml, e.g. db/tls.yml + """ + + def _map(): + return PKDict({p.purebasename: sorted(c.domains) for p, c in _read_tls_d()}) + + pkyaml.dump_pretty(PKDict(default=PKDict(tls_crt=_map())), filename=path) + + def download_first_crt(domain, as_dict=True): """Get the first certificate from domain @@ -294,11 +308,8 @@ def _authority_urn(crt): def _expiring(authority_urn_re): - from rsconf import db - e = datetime.datetime.utcnow() + datetime.timedelta(days=_cfg.expire_days) - for p in pkio.sorted_glob(db.global_path("tls_d").join("*" + CRT_EXT)): - rv = read_crt_as_dict(p) + for p, rv in _read_tls_d(): # The logic here is complicated to allow for self-signed # and authority_urn_re. The former is mostly for testing, # but is applicable if we want to re-issue self-signed @@ -399,6 +410,13 @@ def _is_self_signed_crt(crt): return crt.issuer == crt.subject +def _read_tls_d(): + from rsconf import db + + for p in pkio.sorted_glob(db.global_path("tls_d").join("*" + CRT_EXT)): + yield p, read_crt_as_dict(p) + + def _run(cmd, stderr=subprocess.STDOUT): try: pkdc("{}", " ".join(cmd)) diff --git a/tests/pkcli/tls_data/out.yml b/tests/pkcli/tls_data/out.yml new file mode 100644 index 00000000..f935c600 --- /dev/null +++ b/tests/pkcli/tls_data/out.yml @@ -0,0 +1,8 @@ +default: + tls_crt: + c.c: + - a.a + - b.b + - c.c + d.d: + - d.d diff --git a/tests/pkcli/tls_test.py b/tests/pkcli/tls_test.py index f69cb434..3cc9a479 100644 --- a/tests/pkcli/tls_test.py +++ b/tests/pkcli/tls_test.py @@ -41,3 +41,16 @@ def test_self_signed_and_expiry(): ) pkunit.pkok(e < a.expiry, "expect={} >= actual={}", e, a.expiry) pkunit.pkeq(domains, a.domains) + + +def test_db_yaml(): + from pykern import pkunit, pkio, pkyaml + from pykern.pkdebug import pkdlog, pkdp + from rsconf.pkcli import tls + + with pkunit.save_chdir_work(): + with pkio.save_chdir("db/secret/tls", mkdir=True): + tls.gen_self_signed_crt("c.c", "b.b", "a.a") + tls.gen_self_signed_crt("d.d") + tls.db_yaml("out.yml") + pkunit.file_eq("out.yml")