Merge "Fix system-local-ca ca.crt for upgrades"
This commit is contained in:
commit
2dbd5f0b84
|
@ -4,6 +4,8 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# This script creates/updates required platform certificates during upgrade.
|
||||
# - The secret 'system-local-ca' is updated to include the 'ca.crt' field.
|
||||
#
|
||||
# - Certificates are created using ansible playbooks.
|
||||
# - (Legacy) SX upgrade is already covered by upgrade playbook.
|
||||
#
|
||||
|
@ -15,15 +17,20 @@
|
|||
|
||||
import subprocess
|
||||
import sys
|
||||
import yaml
|
||||
from controllerconfig.common import log
|
||||
from time import sleep
|
||||
import os
|
||||
from time import sleep
|
||||
import yaml
|
||||
|
||||
from controllerconfig.common import log
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from sysinv.common import utils as sysinv_utils
|
||||
from oslo_serialization import base64
|
||||
|
||||
LOG = log.get_logger(__name__)
|
||||
KUBE_CMD = 'kubectl --kubeconfig=/etc/kubernetes/admin.conf '
|
||||
TMP_FILENAME = '/tmp/update_cert.yml'
|
||||
RETRIES = 3
|
||||
TRUSTED_BUNDLE_FILEPATH = '/etc/ssl/certs/ca-cert.pem'
|
||||
|
||||
|
||||
def get_system_mode():
|
||||
|
@ -139,6 +146,61 @@ def get_old_default_CN_by_cert(certificate):
|
|||
return default_CN_by_cert[certificate]
|
||||
|
||||
|
||||
def find_root_ca(intermediate_ca):
|
||||
"""Look in the trusted bundle for the RCA of the ICA provided
|
||||
"""
|
||||
with open(TRUSTED_BUNDLE_FILEPATH, 'r') as file:
|
||||
bundle = file.read().encode('utf-8')
|
||||
for cert_obj in sysinv_utils.extract_certs_from_pem(bundle):
|
||||
cert = cert_obj.public_bytes(
|
||||
serialization.Encoding.PEM).decode('utf-8')
|
||||
if sysinv_utils.verify_cert_issuer(intermediate_ca, cert):
|
||||
return cert
|
||||
LOG.error("Root CA not found for system-local-ca. Data will be empty.")
|
||||
return ""
|
||||
|
||||
|
||||
def update_system_local_ca_secret():
|
||||
"""Update system-local-ca secret
|
||||
"""
|
||||
tls_crt, tls_key, ca_crt = sysinv_utils.get_certificate_from_secret(
|
||||
'system-local-ca', 'cert-manager')
|
||||
|
||||
if ca_crt == "" or not sysinv_utils.verify_cert_issuer(tls_crt, ca_crt):
|
||||
ca_crt = find_root_ca(tls_crt)
|
||||
secret_body = {
|
||||
'apiVersion': 'v1',
|
||||
'kind': 'Secret',
|
||||
'metadata': {
|
||||
'name': 'system-local-ca',
|
||||
'namespace': 'cert-manager'
|
||||
},
|
||||
'type': 'kubernetes.io/tls',
|
||||
'data': {
|
||||
'ca.crt': base64.encode_as_text(ca_crt),
|
||||
'tls.crt': base64.encode_as_text(tls_crt),
|
||||
'tls.key': base64.encode_as_text(tls_key),
|
||||
}
|
||||
}
|
||||
|
||||
with open(TMP_FILENAME, 'w') as yaml_file:
|
||||
yaml.safe_dump(secret_body, yaml_file, default_flow_style=False)
|
||||
|
||||
apply_cmd = KUBE_CMD + 'apply -f ' + TMP_FILENAME
|
||||
|
||||
sub = subprocess.Popen(apply_cmd, shell=True, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
stdout, stderr = sub.communicate()
|
||||
if sub.returncode != 0:
|
||||
LOG.error('Command failed:\n %s\n. %s\n%s\n' % (
|
||||
apply_cmd, stdout.decode('utf-8'), stderr.decode('utf-8')))
|
||||
raise Exception('Cannot apply change to system-local-ca secret.')
|
||||
else:
|
||||
os.remove(TMP_FILENAME)
|
||||
LOG.info('Updated system-local-ca secret. Output:\n%s\n'
|
||||
% stdout.decode('utf-8'))
|
||||
|
||||
|
||||
def update_certificate(certificate, short_name):
|
||||
"""Update the desired subject fields for the certificates
|
||||
"""
|
||||
|
@ -266,6 +328,7 @@ def main():
|
|||
|
||||
for retry in range(0, RETRIES):
|
||||
try:
|
||||
update_system_local_ca_secret()
|
||||
reconfigure_certificates_subject()
|
||||
mode = get_system_mode()
|
||||
# For (legacy) SX upgrade, the role that creates the required
|
||||
|
|
|
@ -482,9 +482,8 @@ class Health(object):
|
|||
err_msg += 'Platform Issuer Root CA certificate is not trusted by the platform.\n'
|
||||
return err_msg
|
||||
else:
|
||||
if not utils.verify_cert_chain_trusted(tls_crt):
|
||||
err_msg += 'Platform Issuer Root CA certificate is not trusted by the platform.\n'
|
||||
return err_msg
|
||||
err_msg += 'Platform Issuer CA certificate chain is incorrect.\n'
|
||||
return err_msg
|
||||
|
||||
return err_msg
|
||||
|
||||
|
|
|
@ -3111,7 +3111,7 @@ def get_certificate_from_secret(secret_name, secret_ns):
|
|||
if 'ca.crt' in data:
|
||||
ca_crt = base64.decode_as_text(data['ca.crt'])
|
||||
else:
|
||||
LOG.warning("Secret does't have CA data stored: %s\\%s" %
|
||||
LOG.warning("Secret doesn't have CA data stored: %s\\%s" %
|
||||
(secret_ns, secret_name))
|
||||
ca_crt = ''
|
||||
except TypeError:
|
||||
|
@ -3172,6 +3172,9 @@ def verify_self_signed_ca_cert(crt):
|
|||
|
||||
|
||||
def verify_cert_issuer(cert, issuer):
|
||||
if cert == issuer:
|
||||
return verify_self_signed_ca_cert(cert)
|
||||
|
||||
tmpfile_crt = tempfile.NamedTemporaryFile()
|
||||
tmpfile_crt.write(
|
||||
extract_certs_from_pem(cert.encode('utf-8'))[-1].public_bytes(serialization.Encoding.PEM))
|
||||
|
|
Loading…
Reference in New Issue