From: Sebastian Wagner Date: Thu, 11 Jul 2019 12:25:57 +0000 (+0200) Subject: pybind/mgr: Remove code duplication X-Git-Tag: v15.1.0~2120^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=a19d166083fdb6d234a3464dbf06cd4f44a46774;p=ceph.git pybind/mgr: Remove code duplication Introduced in #27512 Signed-off-by: Sebastian Wagner --- diff --git a/src/pybind/mgr/ansible/module.py b/src/pybind/mgr/ansible/module.py index 6b87b921f34c..f353d4fb0ebb 100644 --- a/src/pybind/mgr/ansible/module.py +++ b/src/pybind/mgr/ansible/module.py @@ -11,10 +11,10 @@ import os import errno import tempfile import requests -from OpenSSL import crypto, SSL from mgr_module import MgrModule, Option, CLIWriteCommand import orchestrator +from mgr_util import verify_tls_files, ServerConfigException from .ansible_runner_svc import Client, PlayBookExecution, ExecutionStatusCode,\ AnsibleRunnerServiceError @@ -691,9 +691,6 @@ class Module(MgrModule, orchestrator.Orchestrator): configure properly the orchestrator """ - the_crt = None - the_key = None - # Retrieve TLS content to use and check them # First try to get certiticate and key content for this manager instance # ex: mgr/ansible/mgr0/[crt/key] @@ -722,8 +719,10 @@ class Module(MgrModule, orchestrator.Orchestrator): self.client_cert_fname = generate_temp_file("crt", the_crt) self.client_key_fname = generate_temp_file("key", the_key) - self.status_message = verify_tls_files(self.client_cert_fname, - self.client_key_fname) + try: + verify_tls_files(self.client_cert_fname, self.client_key_fname) + except ServerConfigException as e: + self.status_message = str(e) if self.status_message: self.log.error(self.status_message) @@ -854,51 +853,4 @@ def generate_temp_file(key, content): return fname -def verify_tls_files(crt_file, key_file): - """Basic checks for TLS certificate and key files - - :crt_file : Name of the certificate file - :key_file : name of the certificate public key file - - :returns : String with error description - """ - # Check we have files - if not crt_file or not key_file: - return "no certificate/key configured" - - if not os.path.isfile(crt_file): - return "certificate {} does not exist".format(crt_file) - - if not os.path.isfile(key_file): - return "Public key {} does not exist".format(key_file) - - # Do some validations to the private key and certificate: - # - Check the type and format - # - Check the certificate expiration date - # - Check the consistency of the private key - # - Check that the private key and certificate match up - try: - with open(crt_file) as fcrt: - x509 = crypto.load_certificate(crypto.FILETYPE_PEM, fcrt.read()) - if x509.has_expired(): - return "Certificate {} has been expired".format(crt_file) - except (ValueError, crypto.Error) as ex: - return "Invalid certificate {}: {}".format(crt_file, str(ex)) - try: - with open(key_file) as fkey: - pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, fkey.read()) - pkey.check() - except (ValueError, crypto.Error) as ex: - return "Invalid private key {}: {}".format(key_file, str(ex)) - try: - context = SSL.Context(SSL.TLSv1_METHOD) - context.use_certificate_file(crt_file, crypto.FILETYPE_PEM) - context.use_privatekey_file(key_file, crypto.FILETYPE_PEM) - context.check_privatekey() - except crypto.Error as ex: - return "Private key {} and certificate {} do not match up: {}".format( - key_file, crt_file, str(ex)) - - # Everything OK - return "" diff --git a/src/pybind/mgr/dashboard/module.py b/src/pybind/mgr/dashboard/module.py index 868ccdb557ec..2486a164dc70 100644 --- a/src/pybind/mgr/dashboard/module.py +++ b/src/pybind/mgr/dashboard/module.py @@ -13,9 +13,9 @@ import tempfile import threading import time from uuid import uuid4 -from OpenSSL import crypto, SSL +from OpenSSL import crypto from mgr_module import MgrModule, MgrStandbyModule, Option, CLIWriteCommand -from mgr_util import get_default_addr +from mgr_util import get_default_addr, ServerConfigException, verify_tls_files try: import cherrypy @@ -96,10 +96,6 @@ def os_exit_noop(*args): os._exit = os_exit_noop -class ServerConfigException(Exception): - pass - - class CherryPyConfig(object): """ Class for common server configuration done by both active and @@ -193,43 +189,7 @@ class CherryPyConfig(object): else: pkey_fname = self.get_localized_module_option('key_file') - if not cert_fname or not pkey_fname: - raise ServerConfigException('no certificate configured') - if not os.path.isfile(cert_fname): - raise ServerConfigException('certificate %s does not exist' % cert_fname) - if not os.path.isfile(pkey_fname): - raise ServerConfigException('private key %s does not exist' % pkey_fname) - - # Do some validations to the private key and certificate: - # - Check the type and format - # - Check the certificate expiration date - # - Check the consistency of the private key - # - Check that the private key and certificate match up - try: - with open(cert_fname) as f: - x509 = crypto.load_certificate(crypto.FILETYPE_PEM, f.read()) - if x509.has_expired(): - self.log.warning( - 'Certificate {} has been expired'.format(cert_fname)) - except (ValueError, crypto.Error) as e: - raise ServerConfigException( - 'Invalid certificate {}: {}'.format(cert_fname, str(e))) - try: - with open(pkey_fname) as f: - pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, f.read()) - pkey.check() - except (ValueError, crypto.Error) as e: - raise ServerConfigException( - 'Invalid private key {}: {}'.format(pkey_fname, str(e))) - try: - context = SSL.Context(SSL.TLSv1_METHOD) - context.use_certificate_file(cert_fname, crypto.FILETYPE_PEM) - context.use_privatekey_file(pkey_fname, crypto.FILETYPE_PEM) - context.check_privatekey() - except crypto.Error as e: - self.log.warning( - 'Private key {} and certificate {} do not match up: {}'.format( - pkey_fname, cert_fname, str(e))) + verify_tls_files(cert_fname, pkey_fname) config['server.ssl_module'] = 'builtin' config['server.ssl_certificate'] = cert_fname diff --git a/src/pybind/mgr/mgr_util.py b/src/pybind/mgr/mgr_util.py index 331f19d389f3..48ee3b304265 100644 --- a/src/pybind/mgr/mgr_util.py +++ b/src/pybind/mgr/mgr_util.py @@ -1,5 +1,7 @@ import contextlib +import os import socket +import logging ( BLACK, @@ -18,6 +20,8 @@ COLOR_DARK_SEQ = "\033[0;%dm" BOLD_SEQ = "\033[1m" UNDERLINE_SEQ = "\033[4m" +logger = logging.getLogger(__name__) + def colorize(msg, color, dark=False): """ @@ -106,3 +110,57 @@ def get_default_addr(): get_default_addr.result = result return result + +class ServerConfigException(Exception): + pass + + +def verify_tls_files(cert_fname, pkey_fname): + """Basic checks for TLS certificate and key files + + Do some validations to the private key and certificate: + - Check the type and format + - Check the certificate expiration date + - Check the consistency of the private key + - Check that the private key and certificate match up + + :param cert_fname: Name of the certificate file + :param pkey_fname: name of the certificate public key file + + :raises ServerConfigException: An error with a message + + """ + + if not cert_fname or not pkey_fname: + raise ServerConfigException('no certificate configured') + if not os.path.isfile(cert_fname): + raise ServerConfigException('certificate %s does not exist' % cert_fname) + if not os.path.isfile(pkey_fname): + raise ServerConfigException('private key %s does not exist' % pkey_fname) + + from OpenSSL import crypto, SSL + try: + with open(cert_fname) as f: + x509 = crypto.load_certificate(crypto.FILETYPE_PEM, f.read()) + if x509.has_expired(): + logger.warning( + 'Certificate {} has been expired'.format(cert_fname)) + except (ValueError, crypto.Error) as e: + raise ServerConfigException( + 'Invalid certificate {}: {}'.format(cert_fname, str(e))) + try: + with open(pkey_fname) as f: + pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, f.read()) + pkey.check() + except (ValueError, crypto.Error) as e: + raise ServerConfigException( + 'Invalid private key {}: {}'.format(pkey_fname, str(e))) + try: + context = SSL.Context(SSL.TLSv1_METHOD) + context.use_certificate_file(cert_fname, crypto.FILETYPE_PEM) + context.use_privatekey_file(pkey_fname, crypto.FILETYPE_PEM) + context.check_privatekey() + except crypto.Error as e: + logger.warning( + 'Private key {} and certificate {} do not match up: {}'.format( + pkey_fname, cert_fname, str(e)))