diff --git a/fixca/__main__.py b/fixca/__main__.py index 8041b45..6831731 100644 --- a/fixca/__main__.py +++ b/fixca/__main__.py @@ -31,13 +31,19 @@ def main() -> None: add_event_listener(EventType.SHUTDOWN, shutdown) CA.initialize(namespace=args.namespace, secret_name=args.secret, dummy_ca=args.dummy_ca) + CA.store_ca_certs() - common_name = "ca.fix" + common_name = "fixca" cert_key = gen_rsa_key() cert_csr = gen_csr( cert_key, common_name=common_name, - san_dns_names=[common_name], + san_dns_names=[ + common_name, + f"{common_name}.{args.namespace}", + f"{common_name}.{args.namespace}.svc", + f"{common_name}.{args.namespace}.svc.cluster.local", + ], ) cert_crt = CA.sign(cert_csr) with TemporaryDirectory() as tmpdir: diff --git a/fixca/ca.py b/fixca/ca.py index 5fc7194..e9aac27 100644 --- a/fixca/ca.py +++ b/fixca/ca.py @@ -20,7 +20,7 @@ gen_ca_bundle_bytes, ) from resotolib.jwt import encode_jwt, decode_jwt_from_headers -from .k8s import get_secret, set_secret +from .k8s import get_secret, set_secret, get_namespaces from .utils import str_to_bool @@ -143,6 +143,17 @@ def store_secret( data=secret, ) + @requires_initialized + def store_ca_certs(self, exclude_system: bool = True) -> None: + assert self.cert is not None + for namespace in get_namespaces(exclude_system=exclude_system): + log.debug(f"Storing CA cert in {namespace}/fix-ca-cert") + set_secret( + namespace=namespace, + secret_name="fix-ca-cert", + data={"ca.crt": cert_to_bytes(self.cert).decode("utf-8")}, + ) + CA: CertificateAuthority = CertificateAuthority() PSK: Optional[str] = None diff --git a/fixca/k8s.py b/fixca/k8s.py index d62f17d..24b8981 100644 --- a/fixca/k8s.py +++ b/fixca/k8s.py @@ -4,6 +4,8 @@ from resotolib.logger import log from kubernetes import client, config from kubernetes.client.exceptions import ApiException +from kubernetes.client.models.v1_namespace_list import V1NamespaceList +from kubernetes.client.models.v1_namespace import V1Namespace from .utils import memoize @@ -60,3 +62,20 @@ def set_secret(namespace: str, secret_name: str, data: dict[str, str]) -> None: raise else: raise + + +def get_namespaces(exclude_system: bool = True) -> list[str]: + k8s = k8s_client() + + system_namespaces = ["kube-system", "kube-public", "kube-node-lease"] + + try: + namespaces: V1NamespaceList = k8s.list_namespace() + return [ + ns.metadata.name + for ns in namespaces.items + if isinstance(ns, V1Namespace) and (not exclude_system or ns.metadata.name not in system_namespaces) + ] + except ApiException as e: + log.error(f"Failed to fetch namespaces: {e}") + return []