Skip to content

Commit

Permalink
Add cluster config through charm config
Browse files Browse the repository at this point in the history
  • Loading branch information
bschimke95 committed Nov 18, 2024
1 parent 182842d commit e2293e8
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 28 deletions.
10 changes: 4 additions & 6 deletions charms/worker/k8s/charmcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -161,31 +161,29 @@ config:
CIDR to use for Kubernetes services. After deployment it is
only possible to increase the size of the IP range. It is not possible to
change or shrink the address range after deployment.
local-storage.enabled:
local_storage_enabled:
type: boolean
default: true
description: |
Enable local storage provisioning. This will create a storage class
named "local-storage" that uses the hostPath provisioner. This is
useful for development and testing purposes. It is not recommended for
production use.
local-storage.local-path:
local_storage_local_path:
type: string
default: ""
description: |
The path on the host where local storage will be provisioned. This
path must be writable by the kubelet. This is only used if
local-storage.enabled is set to true.
local-storage.reclaim-policy:
local_storage_reclaim_policy:
type: string
description: |
The reclaim policy for local storage. This can be either "Delete" or
"Retain". If set to "Delete", the storage will be deleted when the
PersistentVolumeClaim is deleted. If set to "Retain", the storage will
be retained when the PersistentVolumeClaim is deleted.
local-storage.set-default:
local_storage_set_default:
type: boolean
default: false
description: |
Set the local storage class as the default storage class. This is only
used if local-storage.enabled is set to true.
Expand Down
62 changes: 40 additions & 22 deletions charms/worker/k8s/src/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ def __init__(self, *args):
self.labeller = LabelMaker(
self, kubeconfig_path=self._internal_kubeconfig, kubectl=KUBECTL_PATH
)
self._stored.set_default(is_dying=False, cluster_name=str(), annotations={})
self._stored.set_default(is_dying=False, cluster_name=str(), cluster_config={})

self.cos_agent = COSAgentProvider(
self,
Expand Down Expand Up @@ -296,7 +296,7 @@ def _bootstrap_k8s_snap(self):
bootstrap_config = BootstrapConfig()
self._configure_datastore(bootstrap_config)
self._configure_cloud_provider(bootstrap_config)
self._configure_annotations(bootstrap_config)
self._configure_cluster_config(bootstrap_config)
bootstrap_config.service_cidr = str(self.config["service-cidr"])
bootstrap_config.control_plane_taints = str(self.config["register-with-taints"]).split()
bootstrap_config.extra_sans = [_get_public_address()]
Expand Down Expand Up @@ -372,41 +372,59 @@ def _get_valid_annotations(self) -> Optional[dict]:

return annotations

def _configure_annotations(self, config: BootstrapConfig):
"""Configure the annotations for the Canonical Kubernetes cluster.
def _get_cluster_config_from_charm_config(self) -> UserFacingClusterConfig:
"""Retrieve the cluster config from charm configuration.
Returns:
UserFacingClusterConfig: The expected cluster configuration.
"""
local_storage = LocalStorageConfig(
enabled=self.config.get("local_storage_enabled"),
local_path=self.config.get("local_storage_local_path"),
reclaim_policy=self.config.get("local_storage_reclaim_policy"),
set_default=self.config.get("local_storage_set_default"),
)

return UserFacingClusterConfig(
local_storage=local_storage,
annotations=self._get_valid_annotations(),
)

def _configure_cluster_config(self, config: BootstrapConfig):
"""Configure the cluster config for the Canonical Kubernetes cluster.
Args:
config (BootstrapConfig): Configuration object to bootstrap the cluster.
"""
annotations = self._get_valid_annotations()
if annotations is None:
return

if not config.cluster_config:
config.cluster_config = UserFacingClusterConfig(annotations=annotations)
config.cluster_config = self._get_cluster_config_from_charm_config()
else:
config.cluster_config.annotations = annotations
charm_cluster_config = self._get_cluster_config_from_charm_config()
# Merge the charm and user cluster configurations
# The existing configuration takes precedence over the charm configuration as
# this information is retrieved elsewhere (e.g. cloud-provider).
merged_data = {**charm_cluster_config.dict(), **config.cluster_config.dict()}
config.cluster_config = UserFacingClusterConfig(**merged_data)

@status.on_error(
ops.BlockedStatus("Invalid Annotations"),
ops.BlockedStatus("Invalid Cluster configuration"),
AssertionError,
)
def _update_annotations(self):
"""Update the annotations for the Canonical Kubernetes cluster."""
annotations = self._get_valid_annotations()
if annotations is None:
return
def _update_cluster_config(self):
"""Update the cluster configuration for the Canonical Kubernetes cluster."""
status.add(ops.MaintenanceStatus("Updating cluster configuration"))
log.info("Updating cluster configuration")

status.add(ops.MaintenanceStatus("Updating Annotations"))
log.info("Updating Annotations")
cluster_config = self._get_cluster_config_from_charm_config()

if self._stored.annotations == annotations:
if self._stored.cluster_config == cluster_config:
return

config = UserFacingClusterConfig(annotations=annotations)
update_request = UpdateClusterConfigRequest(config=config)
update_request = UpdateClusterConfigRequest(config=cluster_config)
self.api_manager.update_cluster_config(update_request)

self._stored.cluster_config = cluster_config

def _configure_datastore(self, config: Union[BootstrapConfig, UpdateClusterConfigRequest]):
"""Configure the datastore for the Kubernetes cluster.
Expand Down Expand Up @@ -737,7 +755,7 @@ def _reconcile(self, event: ops.EventBase):
self._k8s_info(event)
self._bootstrap_k8s_snap()
self._enable_functionalities()
self._update_annotations()
self._update_cluster_config()
self._create_cluster_tokens()
self._create_cos_tokens()
self._apply_cos_requirements()
Expand Down

0 comments on commit e2293e8

Please sign in to comment.