Skip to content

Commit

Permalink
Add kube-apiserver-extra-sans option
Browse files Browse the repository at this point in the history
We're adding a config option that allows specifying additional
kube-apiserver Subject Alternative Names.
  • Loading branch information
petrutlucian94 committed Dec 3, 2024
1 parent 638de69 commit 5634d03
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 2 deletions.
11 changes: 11 additions & 0 deletions charms/worker/k8s/charmcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,17 @@ config:
runtime-config=batch/v2alpha1=true profiling=true
will result in kube-apiserver being run with the following options:
--runtime-config=batch/v2alpha1=true --profiling=true
kube-apiserver-extra-sans:
type: string
default: ""
description: |
Space separated list of extra Subject Alternative Names for the kube-apiserver
self-signed certificates.
Examples:
- "kubernetes"
- "kubernetes.default.svc"
- "kubernetes.default.svc.cluster.local"
kube-controller-manager-extra-args:
type: string
default: ""
Expand Down
11 changes: 9 additions & 2 deletions charms/worker/k8s/src/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,13 @@ def _check_k8sd_ready(self):
status.add(ops.MaintenanceStatus("Ensuring snap readiness"))
self.api_manager.check_k8sd_ready()

def _get_extra_sans(self):
"""Retrieve the certificate extra SANs."""
extra_sans_str = str(self.config.get("kube-apiserver-extra-sans") or "")
configured_sans = {san for san in extra_sans_str.strip().split() if san}
all_sans = configured_sans | set([_get_public_address()])
return sorted(all_sans)

def _assemble_bootstrap_config(self):
"""Assemble the bootstrap configuration for the Kubernetes cluster.
Expand All @@ -329,7 +336,7 @@ def _assemble_bootstrap_config(self):
bootstrap_config.service_cidr = str(self.config["bootstrap-service-cidr"])
bootstrap_config.pod_cidr = str(self.config["bootstrap-pod-cidr"])
bootstrap_config.control_plane_taints = str(self.config["bootstrap-node-taints"]).split()
bootstrap_config.extra_sans = [_get_public_address()]
bootstrap_config.extra_sans = self._get_extra_sans()
cluster_name = self.get_cluster_name()
config.extra_args.craft(self.config, bootstrap_config, cluster_name)
return bootstrap_config
Expand Down Expand Up @@ -761,7 +768,7 @@ def _join_with_token(self, relation: ops.Relation, token: str, cluster_name: str
request = JoinClusterRequest(name=node_name, address=cluster_addr, token=token)
if self.is_control_plane:
request.config = ControlPlaneNodeJoinConfig()
request.config.extra_sans = [_get_public_address()]
request.config.extra_sans = self._get_extra_sans()
config.extra_args.craft(self.config, request.config, cluster_name)
else:
request.config = NodeJoinConfig()
Expand Down
25 changes: 25 additions & 0 deletions charms/worker/k8s/tests/unit/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,28 @@ def test_configure_datastore_runtime_config_etcd(harness):
assert uccr_config.datastore.client_key == ""
assert uccr_config.datastore.servers == ["foo:1234", "bar:1234"]
assert uccr_config.datastore.type == "external"


def test_configure_boostrap_extra_sans(harness):
"""Test configuring kube-apiserver-extra-sans on bootstrap.
Args:
harness: the harness under test
"""
if harness.charm.is_worker:
pytest.skip("Not applicable on workers")

cfg_extra_sans = ["mykubernetes", "mykubernetes.local"]
public_addr = "11.12.13.14"
harness.update_config({"kube-apiserver-extra-sans": " ".join(cfg_extra_sans)})

with mock.patch("charm._get_public_address") as mock_get_public_addr:
mock_get_public_addr.return_value = public_addr

bs_config = harness.charm._assemble_bootstrap_config()

# We expect the resulting SANs to include the configured addresses as well
# as the unit address.
exp_extra_sans = cfg_extra_sans + [public_addr]
for san in exp_extra_sans:
assert san in bs_config.extra_sans

0 comments on commit 5634d03

Please sign in to comment.