Skip to content

Commit c93703f

Browse files
Split test for tls.crt and ca.crt (#54)
Some new certs do not have a ca.crt so were being excluded from prometheus output. Added logging too. Signed-off-by: Andrew Perry <[email protected]> Signed-off-by: Ricky Moorhouse <[email protected]>
1 parent 50684e7 commit c93703f

File tree

1 file changed

+89
-35
lines changed

1 file changed

+89
-35
lines changed

certs_net.py

Lines changed: 89 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import requests
2-
import logging
2+
import alog
33
from kubernetes import client, config
44
from prometheus_client import Gauge
55
import urllib3
@@ -8,61 +8,115 @@
88
import ssl, socket
99
import datetime
1010
import time
11+
import sys
1112

1213
urllib3.disable_warnings()
13-
logger = logging.getLogger(__name__)
14-
15-
1614

1715
class CertsNet(object):
1816
namespace = None
1917
use_kubeconfig = True
2018
trawler = None
19+
logger = None
2120

22-
def __init__(self, config, trawler):
21+
def __init__(self, config, trawler=None, logger=None):
2322
# Takes in config object and trawler instance it's behind
2423
# Use kubeconfig or in-cluster config for k8s comms
2524
if trawler:
2625
self.trawler = trawler
27-
self.use_kubeconfig = trawler.use_kubeconfig
26+
self.use_kubeconfig = self.trawler.use_kubeconfig
27+
if logger:
28+
self.logger = logger
29+
else:
30+
alog.configure(default_level="info")
31+
self.logger = alog.use_channel("certs_net")
32+
self.logger.info("Init CertsNet")
2833
# Namespace to review
2934
self.namespace = config.get('namespace', None)
3035

36+
3137
def getExpiry(self, cert_data):
32-
cert = base64.b64decode(cert_data)
33-
x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert)
34-
expiry = datetime.datetime.strptime(x509.get_notAfter().decode('utf-8'), "%Y%m%d%H%M%S%z").timestamp()
35-
return int(expiry - time.time())
38+
try:
39+
cert = base64.b64decode(cert_data)
40+
x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert)
41+
expiry = datetime.datetime.strptime(x509.get_notAfter().decode('utf-8'), "%Y%m%d%H%M%S%z").timestamp()
42+
return int(expiry - time.time())
43+
except:
44+
self.logger.exception("getExpiry failed")
45+
return None
3646

47+
@alog.timed_function(alog.use_channel("fish").trace)
3748
def fish(self):
3849
# Go fishing
39-
# Load appropriate k8s config
40-
if self.use_kubeconfig:
41-
config.load_kube_config()
42-
else:
43-
config.load_incluster_config()
44-
# Initialise the k8s API
45-
v1 = client.CoreV1Api()
46-
# Retreive secret list for specified namespace if specified, otherwise all namespaces
47-
if self.namespace:
48-
ret = v1.list_namespaced_secret(namespace=self.namespace)
49-
else:
50-
ret = v1.list_secret_for_all_namespaces()
50+
if self.logger:
51+
self.logger.info("Starting to fish")
52+
try:
53+
# Load appropriate k8s config
54+
if self.use_kubeconfig:
55+
config.load_kube_config()
56+
else:
57+
config.load_incluster_config()
58+
except:
59+
self.logger.exception("fish: loading kubeconfig failed")
60+
61+
try:
62+
# Initialise the k8s API
63+
v1 = client.CoreV1Api()
64+
except:
65+
self.logger.exception("fish: loading kubenetes CoreV1Api failed")
66+
return
5167

68+
try:
69+
# Retreive secret list for specified namespace if specified, otherwise all namespaces
70+
if self.namespace:
71+
self.logger.info("CertsNet: Getting secrets for namespace {}".format(self.namespace))
72+
ret = v1.list_namespaced_secret(namespace=self.namespace)
73+
else:
74+
self.logger.info("CertsNet: Getting secrets for all namespaces")
75+
ret = v1.list_secret_for_all_namespaces()
76+
except:
77+
self.logger.exception("fish: retrieving kubenetes secrets failed")
78+
return
79+
80+
tls_secrets_found = 0
81+
secrets_processed = 0
5282
for secret in ret.items:
53-
if secret.type == 'kubernetes.io/tls' and 'ca.crt' in secret.data and secret.data['ca.crt'] != '':
54-
caSecondsLeft = self.getExpiry(secret.data['ca.crt'])
55-
tlsSecondsLeft = self.getExpiry(secret.data['tls.crt'])
56-
self.trawler.set_gauge(
57-
'cert', 'remaining_seconds',
58-
tlsSecondsLeft,
59-
labels={'secret':secret.metadata.name, 'cert':'tls.crt', 'namespace': secret.metadata.namespace})
60-
self.trawler.set_gauge(
61-
'cert', 'remaining_seconds',
62-
caSecondsLeft,
63-
labels={'secret':secret.metadata.name, 'cert':'ca.crt', 'namespace': secret.metadata.namespace})
83+
if secret.type == 'kubernetes.io/tls':
84+
tls_secrets_found += 1
85+
this_secret_counted = False
86+
if 'tls.crt' in secret.data and secret.data['tls.crt'] != '':
87+
self.logger.trace("Processing tls.crt for secret {}".format(secret.metadata.name))
88+
tlsSecondsLeft = self.getExpiry(secret.data['tls.crt'])
89+
if tlsSecondsLeft == None:
90+
continue
91+
if self.trawler:
92+
self.trawler.set_gauge(
93+
'cert', 'remaining_seconds',
94+
tlsSecondsLeft,
95+
labels={'secret':secret.metadata.name, 'cert':'tls.crt', 'namespace': secret.metadata.namespace})
96+
this_secret_counted = True
97+
secrets_processed += 1
98+
if 'ca.crt' in secret.data and secret.data['ca.crt'] != '':
99+
self.logger.trace("Processing ca.crt for secret {}".format(secret.metadata.name))
100+
caSecondsLeft = self.getExpiry(secret.data['ca.crt'])
101+
if caSecondsLeft == None:
102+
continue
103+
if self.trawler:
104+
self.trawler.set_gauge(
105+
'cert', 'remaining_seconds',
106+
caSecondsLeft,
107+
labels={'secret':secret.metadata.name, 'cert':'ca.crt', 'namespace': secret.metadata.namespace})
108+
if not this_secret_counted:
109+
secrets_processed += 1
110+
else:
111+
self.logger.trace("No ca.crt for secret {}".format(secret.metadata.name))
112+
if self.logger:
113+
self.logger.info("Finished fish. Processed {}/{}".format(secrets_processed, tls_secrets_found))
114+
64115

65-
66116
if __name__ == "__main__":
67-
net = CertsNet(config={'namespace':'apic'}, trawler=None)
117+
test_logger = None
118+
if len(sys.argv) > 1:
119+
alog.configure(default_level="trace")
120+
test_logger = alog.use_channel("mocktrawler")
121+
net = CertsNet(config={'namespace':'apic'}, trawler=None, logger=test_logger)
68122
net.fish()

0 commit comments

Comments
 (0)