From b25805f01c9fd3de2ad96acb52f82a97ce49615a Mon Sep 17 00:00:00 2001 From: Mike Wilson Date: Tue, 24 Oct 2017 14:31:56 -0400 Subject: [PATCH] Adding extra_sans option to load balancer to allow custom SAN entries on the certificate Adding support for restarting nginx on the load balancer Added better support for knowing when certificates are written. This helps the master restart the apiserver appropriately. --- .../layers/kubeapi-load-balancer/config.yaml | 6 +++++ .../reactive/load_balancer.py | 26 +++++++++++++++++++ .../reactive/kubernetes_master.py | 13 +++++----- 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/cluster/juju/layers/kubeapi-load-balancer/config.yaml b/cluster/juju/layers/kubeapi-load-balancer/config.yaml index ad33ef60adc..a4678ae02f3 100644 --- a/cluster/juju/layers/kubeapi-load-balancer/config.yaml +++ b/cluster/juju/layers/kubeapi-load-balancer/config.yaml @@ -3,3 +3,9 @@ options: type: int default: 443 description: The port to run the loadbalancer + extra_sans: + type: string + default: "" + description: | + Space-separated list of extra SAN entries to add to the x509 certificate + created for the load balancers. diff --git a/cluster/juju/layers/kubeapi-load-balancer/reactive/load_balancer.py b/cluster/juju/layers/kubeapi-load-balancer/reactive/load_balancer.py index 8ed601e3cd3..bd4a2bbb9d6 100644 --- a/cluster/juju/layers/kubeapi-load-balancer/reactive/load_balancer.py +++ b/cluster/juju/layers/kubeapi-load-balancer/reactive/load_balancer.py @@ -22,7 +22,9 @@ from charms import layer from charms.reactive import when, when_any, when_not from charms.reactive import set_state, remove_state from charmhelpers.core import hookenv +from charmhelpers.core import host from charmhelpers.contrib.charmsupport import nrpe +from charms.reactive.helpers import data_changed from charms.layer import nginx @@ -44,12 +46,36 @@ def request_server_certificates(tls): hookenv.unit_private_ip(), socket.gethostname(), ] + # maybe they have extra names they want as SANs + extra_sans = hookenv.config('extra_sans') + if extra_sans and not extra_sans == "": + sans.extend(extra_sans.split()) # Create a path safe name by removing path characters from the unit name. certificate_name = hookenv.local_unit().replace('/', '_') # Request a server cert with this information. tls.request_server_cert(common_name, sans, certificate_name) +@when('config.changed.extra_sans', 'certificates.available') +def update_certificate(tls): + # Using the config.changed.extra_sans flag to catch changes. + # IP changes will take ~5 minutes or so to propagate, but + # it will update. + request_server_certificates(tls) + + +@when('certificates.server.cert.available', + 'nginx.available', 'tls_client.server.certificate.written') +def kick_nginx(tls): + # we are just going to sighup it, but still want to avoid kicking it + # without need + if data_changed('cert', tls.get_server_cert()): + # certificate changed, so sighup nginx + hookenv.log("Certificate information changed, sending SIGHUP to nginx") + host.service_restart('nginx') + remove_state('tls_client.server.certificate.written') + + @when('config.changed.port') def close_old_port(): config = hookenv.config() diff --git a/cluster/juju/layers/kubernetes-master/reactive/kubernetes_master.py b/cluster/juju/layers/kubernetes-master/reactive/kubernetes_master.py index 1b5b83967ab..87cd4f4b3a9 100644 --- a/cluster/juju/layers/kubernetes-master/reactive/kubernetes_master.py +++ b/cluster/juju/layers/kubernetes-master/reactive/kubernetes_master.py @@ -469,17 +469,17 @@ def send_data(tls): tls.request_server_cert(common_name, sans, certificate_name) -@when('config.changed', 'certificates.available') +@when('config.changed.extra_sans', 'certificates.available') def update_certificate(tls): - # I using the config.changed flag instead of something more - # specific to try and catch ip changes. Being a little - # spammy here is ok because the cert layer checks for - # changes to the cert before issuing a new one + # Using the config.changed.extra_sans flag to catch changes. + # IP changes will take ~5 minutes or so to propagate, but + # it will update. send_data(tls) @when('certificates.server.cert.available', - 'kubernetes-master.components.started') + 'kubernetes-master.components.started', + 'tls_client.server.certificate.written') def kick_api_server(tls): # need to be idempotent and don't want to kick the api server # without need @@ -487,6 +487,7 @@ def kick_api_server(tls): # certificate changed, so restart the api server hookenv.log("Certificate information changed, restarting api server") set_state('kube-apiserver.do-restart') + remove_state('tls_client.server.certificate.written') @when('kubernetes-master.components.started')