summaryrefslogtreecommitdiffstats
path: root/roles/openshift_certificate_expiry
diff options
context:
space:
mode:
Diffstat (limited to 'roles/openshift_certificate_expiry')
-rw-r--r--roles/openshift_certificate_expiry/README.md20
-rw-r--r--roles/openshift_certificate_expiry/filter_plugins/oo_cert_expiry.py28
-rw-r--r--roles/openshift_certificate_expiry/library/openshift_cert_expiry.py85
3 files changed, 84 insertions, 49 deletions
diff --git a/roles/openshift_certificate_expiry/README.md b/roles/openshift_certificate_expiry/README.md
index d44438332..a88470bdd 100644
--- a/roles/openshift_certificate_expiry/README.md
+++ b/roles/openshift_certificate_expiry/README.md
@@ -9,7 +9,7 @@ include:
* Master/Node Service Certificates
* Router/Registry Service Certificates from etcd secrets
* Master/Node/Router/Registry/Admin `kubeconfig`s
-* Etcd certificates
+* Etcd certificates (including embedded)
This role pairs well with the redeploy certificates playbook:
@@ -111,12 +111,16 @@ There are two top-level keys in the saved JSON results, `data` and
`summary`.
The `data` key is a hash where the keys are the names of each host
-examined and the values are the check results for each respective
-host.
+examined and the values are the check results for the certificates
+identified on each respective host.
-The `summary` key is a hash that summarizes the number of certificates
-expiring within the configured warning window and the number of
-already expired certificates.
+The `summary` key is a hash that summarizes the total number of
+certificates:
+
+* examined on the entire cluster
+* OK
+* expiring within the configured warning window
+* already expired
The example below is abbreviated to save space:
@@ -193,7 +197,9 @@ The example below is abbreviated to save space:
},
"summary": {
"warning": 6,
- "expired": 0
+ "expired": 0,
+ "total": 7,
+ "ok": 1
}
}
```
diff --git a/roles/openshift_certificate_expiry/filter_plugins/oo_cert_expiry.py b/roles/openshift_certificate_expiry/filter_plugins/oo_cert_expiry.py
index 2e2430ee6..5f102e960 100644
--- a/roles/openshift_certificate_expiry/filter_plugins/oo_cert_expiry.py
+++ b/roles/openshift_certificate_expiry/filter_plugins/oo_cert_expiry.py
@@ -5,29 +5,6 @@
Custom filters for use in openshift-ansible
"""
-from ansible import errors
-from collections import Mapping
-from distutils.util import strtobool
-from distutils.version import LooseVersion
-from operator import itemgetter
-import OpenSSL.crypto
-import os
-import pdb
-import pkg_resources
-import re
-import json
-import yaml
-from ansible.parsing.yaml.dumper import AnsibleDumper
-from urlparse import urlparse
-
-try:
- # ansible-2.2
- # ansible.utils.unicode.to_unicode is deprecated in ansible-2.2,
- # ansible.module_utils._text.to_text should be used instead.
- from ansible.module_utils._text import to_text
-except ImportError:
- # ansible-2.1
- from ansible.utils.unicode import to_unicode as to_text
# Disabling too-many-public-methods, since filter methods are necessarily
# public
@@ -74,13 +51,16 @@ Example playbook usage:
total_warnings = sum([hostvars[h]['check_results']['summary']['warning'] for h in play_hosts])
total_expired = sum([hostvars[h]['check_results']['summary']['expired'] for h in play_hosts])
+ total_ok = sum([hostvars[h]['check_results']['summary']['ok'] for h in play_hosts])
+ total_total = sum([hostvars[h]['check_results']['summary']['total'] for h in play_hosts])
json_result['summary']['warning'] = total_warnings
json_result['summary']['expired'] = total_expired
+ json_result['summary']['ok'] = total_ok
+ json_result['summary']['total'] = total_total
return json_result
-
def filters(self):
""" returns a mapping of filters to methods """
return {
diff --git a/roles/openshift_certificate_expiry/library/openshift_cert_expiry.py b/roles/openshift_certificate_expiry/library/openshift_cert_expiry.py
index 2cdb87dc1..a474b36b0 100644
--- a/roles/openshift_certificate_expiry/library/openshift_cert_expiry.py
+++ b/roles/openshift_certificate_expiry/library/openshift_cert_expiry.py
@@ -4,17 +4,13 @@
"""For details on this module see DOCUMENTATION (below)"""
-# router/registry cert grabbing
-import subprocess
-# etcd config file
-import ConfigParser
-# Expiration parsing
import datetime
-# File path stuff
import os
-# Config file parsing
+import subprocess
+
+from six.moves import configparser
+
import yaml
-# Certificate loading
import OpenSSL.crypto
DOCUMENTATION = '''
@@ -260,7 +256,10 @@ Return:
# This is our module MAIN function after all, so there's bound to be a
# lot of code bundled up into one block
#
-# pylint: disable=too-many-locals,too-many-locals,too-many-statements,too-many-branches
+# Reason: These checks are disabled because the issue was introduced
+# during a period where the pylint checks weren't enabled for this file
+# Status: temporarily disabled pending future refactoring
+# pylint: disable=too-many-locals,too-many-statements,too-many-branches
def main():
"""This module examines certificates (in various forms) which compose
an OpenShift Container Platform cluster
@@ -371,7 +370,7 @@ an OpenShift Container Platform cluster
######################################################################
# Load the certificate and the CA, parse their expiration dates into
# datetime objects so we can manipulate them later
- for _, v in cert_meta.iteritems():
+ for _, v in cert_meta.items():
with open(v, 'r') as fp:
cert = fp.read()
cert_subject, cert_expiry_date, time_remaining = load_and_handle_cert(cert, now)
@@ -467,7 +466,11 @@ an OpenShift Container Platform cluster
######################################################################
# Check etcd certs
+ #
+ # Two things to check: 'external' etcd, and embedded etcd.
######################################################################
+ # FIRST: The 'external' etcd
+ #
# Some values may be duplicated, make this a set for now so we
# unique them all
etcd_certs_to_check = set([])
@@ -475,13 +478,17 @@ an OpenShift Container Platform cluster
etcd_cert_params.append('dne')
try:
with open('/etc/etcd/etcd.conf', 'r') as fp:
- etcd_config = ConfigParser.ConfigParser()
+ etcd_config = configparser.ConfigParser()
+ # Reason: This check is disabled because the issue was introduced
+ # during a period where the pylint checks weren't enabled for this file
+ # Status: temporarily disabled pending future refactoring
+ # pylint: disable=deprecated-method
etcd_config.readfp(FakeSecHead(fp))
for param in etcd_cert_params:
try:
etcd_certs_to_check.add(etcd_config.get('ETCD', param))
- except ConfigParser.NoOptionError:
+ except configparser.NoOptionError:
# That parameter does not exist, oh well...
pass
except IOError:
@@ -506,6 +513,43 @@ an OpenShift Container Platform cluster
classify_cert(expire_check_result, now, time_remaining, expire_window, etcd_certs)
######################################################################
+ # Now the embedded etcd
+ ######################################################################
+ try:
+ with open('/etc/origin/master/master-config.yaml', 'r') as fp:
+ cfg = yaml.load(fp)
+ except IOError:
+ # Not present
+ pass
+ else:
+ if cfg.get('etcdConfig', {}).get('servingInfo', {}).get('certFile', None) is not None:
+ # This is embedded
+ etcd_crt_name = cfg['etcdConfig']['servingInfo']['certFile']
+ else:
+ # Not embedded
+ etcd_crt_name = None
+
+ if etcd_crt_name is not None:
+ # etcd_crt_name is relative to the location of the
+ # master-config.yaml file
+ cfg_path = os.path.dirname(fp.name)
+ etcd_cert = os.path.join(cfg_path, etcd_crt_name)
+ with open(etcd_cert, 'r') as etcd_fp:
+ (cert_subject,
+ cert_expiry_date,
+ time_remaining) = load_and_handle_cert(etcd_fp.read(), now)
+
+ expire_check_result = {
+ 'cert_cn': cert_subject,
+ 'path': etcd_fp.name,
+ 'expiry': cert_expiry_date,
+ 'days_remaining': time_remaining.days,
+ 'health': None,
+ }
+
+ classify_cert(expire_check_result, now, time_remaining, expire_window, etcd_certs)
+
+ ######################################################################
# /Check etcd certs
######################################################################
@@ -523,7 +567,7 @@ an OpenShift Container Platform cluster
######################################################################
# First the router certs
try:
- router_secrets_raw = subprocess.Popen('oc get secret router-certs -o yaml'.split(),
+ router_secrets_raw = subprocess.Popen('oc get -n default secret router-certs -o yaml'.split(),
stdout=subprocess.PIPE)
router_ds = yaml.load(router_secrets_raw.communicate()[0])
router_c = router_ds['data']['tls.crt']
@@ -552,7 +596,7 @@ an OpenShift Container Platform cluster
######################################################################
# Now for registry
try:
- registry_secrets_raw = subprocess.Popen('oc get secret registry-certificates -o yaml'.split(),
+ registry_secrets_raw = subprocess.Popen('oc get -n default secret registry-certificates -o yaml'.split(),
stdout=subprocess.PIPE)
registry_ds = yaml.load(registry_secrets_raw.communicate()[0])
registry_c = registry_ds['data']['registry.crt']
@@ -613,9 +657,13 @@ an OpenShift Container Platform cluster
# will be at the front of the list and certificates which will
# expire later are at the end. Router and registry certs should be
# limited to just 1 result, so don't bother sorting those.
- check_results['ocp_certs'] = sorted(check_results['ocp_certs'], cmp=lambda x, y: cmp(x['days_remaining'], y['days_remaining']))
- check_results['kubeconfigs'] = sorted(check_results['kubeconfigs'], cmp=lambda x, y: cmp(x['days_remaining'], y['days_remaining']))
- check_results['etcd'] = sorted(check_results['etcd'], cmp=lambda x, y: cmp(x['days_remaining'], y['days_remaining']))
+ def cert_key(item):
+ ''' return the days_remaining key '''
+ return item['days_remaining']
+
+ check_results['ocp_certs'] = sorted(check_results['ocp_certs'], key=cert_key)
+ check_results['kubeconfigs'] = sorted(check_results['kubeconfigs'], key=cert_key)
+ check_results['etcd'] = sorted(check_results['etcd'], key=cert_key)
# This module will never change anything, but we might want to
# change the return code parameter if there is some catastrophic
@@ -628,10 +676,11 @@ an OpenShift Container Platform cluster
changed=False
)
+
######################################################################
# It's just the way we do things in Ansible. So disable this warning
#
# pylint: disable=wrong-import-position,import-error
-from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.basic import AnsibleModule # noqa: E402
if __name__ == '__main__':
main()