import os import argparse import yaml from kubernetes import client, config import base64 import time import csv from datetime import datetime parser = argparse.ArgumentParser(description='check shoot certificate expiration') parser.add_argument('--gardenConfig', type=str) parser.add_argument('--gardenNs', type=str) parser.add_argument('--outfile', type=str) args = parser.parse_args() print(args.gardenConfig) gardenConfig = args.gardenConfig gardenNs = args.gardenNs outfile = args.outfile csvFile = open(outfile, 'w', newline='') fieldnames = ['shoot', 'cluster', 'secret','expiredate', "issuer"] writer = csv.DictWriter(csvFile, fieldnames=fieldnames) writer.writeheader() config.kube_config.load_kube_config(config_file=gardenConfig) apiClient = client.CoreV1Api() shootClient = client.CustomObjectsApi() shoots = shootClient.list_namespaced_custom_object( group="core.gardener.cloud", version="v1beta1", namespace=gardenNs, plural="shoots", ) def get_tc_from_shoot(shootName, writer): apiClient = client.CoreV1Api() namespaces = apiClient.list_namespace() for ns in namespaces.items: tcClient = client.CustomObjectsApi() tcs = tcClient.list_namespaced_custom_object( group="pingcap.com", version="v1alpha1", namespace=ns.metadata.name, plural="tidbclusters") if len(tcs['items']) == 0: print("the tc is deleted, pass") continue certs = tcClient.list_namespaced_custom_object( group="cert-manager.io", version="v1alpha3", namespace=ns.metadata.name, plural="certificates") for cert in certs['items']: print("Shoot:{0} namespace:{1} Secret:{2}, Issuer {3}".format( shootName, ns.metadata.name, cert["spec"]["secretName"], cert["spec"]["issuerRef"]["name"])) ca = apiClient.read_namespaced_secret(cert["spec"]["secretName"], ns.metadata.name) ca = ca.data['ca.crt'] if(ca == ""): writer.writerow({'shoot': shootName, 'cluster': ns.metadata.name, 'secret': cert["spec"]["secretName"], 'expiredate': 'unknow', 'issuer': cert["spec"]["issuerRef"]["name"]}) continue # print(ca) ca = base64.b64decode(ca) certCaFile= open(cert["spec"]["secretName"] , "wb") certCaFile.write(ca) certCaFile.close() nowtime = os.popen('openssl x509 -in {0} -noout -dates'.format(cert["spec"]["secretName"])) lines= nowtime.readlines() if(len(lines) <2): continue lines[0] = lines[0].replace("notBefore=", "").replace("\n","") lines[1] = lines[1].replace("notAfter=", "").replace("\n","") endDate=lines[1] # end = time.strptime(lines[1], "%b %d %H:%M:%S %Y GMT") # end = time.mktime(end) print("Shoot:{0} namespace:{1} Secret:{2} CA will expire. ExpireDate is {3}, Issuer {4}".format( shootName, ns.metadata.name, cert["spec"]["secretName"], endDate, cert["spec"]["issuerRef"]["name"])) writer.writerow({'shoot': shootName, 'cluster': ns.metadata.name, 'secret': cert["spec"]["secretName"], 'expiredate': endDate, 'issuer': cert["spec"]["issuerRef"]["name"]}) for shoot in shoots['items']: config.kube_config.load_kube_config(config_file=gardenConfig) shootName = shoot["metadata"]["name"] print("process shoot ", shootName) shootKubeconfigSecretName = shootName + ".kubeconfig" if shoot["metadata"]["labels"]["shoot.gardener.cloud/status"] != "healthy": continue shootKubeconfig = apiClient.read_namespaced_secret(shootKubeconfigSecretName, gardenNs) shootKubeconfig = shootKubeconfig.data["kubeconfig"] shootKubeconfig= base64.b64decode(shootKubeconfig) shootKubeconfigFile= open(shootName , "w") yaml.dump(yaml.load(shootKubeconfig), shootKubeconfigFile) shootKubeconfigFile.close() config.kube_config.load_kube_config(config_file=shootName) get_tc_from_shoot(shootName, writer) csvFile.close()