diff --git a/config.yaml b/config.yaml index 7724dda..40d1c81 100644 --- a/config.yaml +++ b/config.yaml @@ -85,9 +85,22 @@ options: The current release deployed is available by viewing juju status vsphere-cloud-provider + storage-class-parameters: + type: string + description: | + Specify extra parmeters to the default storage class installed. + Each parameter is separated by commas and are key=value pairs + + example) + storagepolicyname=vSAN Default Storage Policy + storagepolicyname=vSAN Default Storage Policy,datastoreurl=ds:///vmfs/volumes/vsan:52cdfa80721ff516-ea1e993113acfc77/ + + default: 'storagepolicyname=vSAN Default Storage Policy' + csi-migration: description: | Enables the CSIMigration feature of the storage-provider allowing the driver plugin to migrate in-tree volumes to the out-of-tree provider. type: string default: "false" + diff --git a/src/charm.py b/src/charm.py index eb476db..4c9b5d6 100755 --- a/src/charm.py +++ b/src/charm.py @@ -217,7 +217,7 @@ def _install_or_upgrade(self, event, config_hash=None): controller.apply_manifests() except ManifestClientError as e: self.unit.status = WaitingStatus("Waiting for kube-apiserver") - log.warn(f"Encountered retryable installation error: {e}") + log.warning(f"Encountered retryable installation error: {e}") event.defer() return False return True diff --git a/src/storage_manifests.py b/src/storage_manifests.py index 1b04bfd..06b952b 100644 --- a/src/storage_manifests.py +++ b/src/storage_manifests.py @@ -126,6 +126,18 @@ def __init__(self, manifests: "Manifests", sc_type: str): super().__init__(manifests) self.type = sc_type + @property + def _params(self) -> Dict[str, str]: + parameter_config = self.manifests.config["storage-class-parameters"] + parameters = {} + for param in parameter_config.split(","): + try: + key, val = param.split("=", 1) + parameters[key] = val + except ValueError: + log.error("Storage class parameter missing '=' separator in '%s'", param) + return parameters + def __call__(self) -> Optional[AnyResource]: """Craft the storage class object.""" storage_name = STORAGE_CLASS_NAME.format(type=self.type) @@ -141,7 +153,7 @@ def __call__(self) -> Optional[AnyResource]: }, ), provisioner="csi.vsphere.vmware.com", - parameters=dict(storagepolicyname="vSAN Default Storage Policy"), + parameters=self._params, ) ) diff --git a/tests/unit/test_storage_manifests.py b/tests/unit/test_storage_manifests.py new file mode 100644 index 0000000..9004cab --- /dev/null +++ b/tests/unit/test_storage_manifests.py @@ -0,0 +1,26 @@ +# Copyright 2023 Canonical Ltd. +# See LICENSE file for licensing details. +# +# Learn more about testing at: https://juju.is/docs/sdk/testing + + +from unittest import mock + +from storage_manifests import CreateStorageClass + + +def test_parse_parameter_config(): + mock_manifests = mock.MagicMock() + mock_manifests.config = {"storage-class-parameters": "key=val,something=test with spaces"} + sc = CreateStorageClass(mock_manifests, "default") + assert sc._params == {"key": "val", "something": "test with spaces"} + + +def test_parse_parameter_invalid(caplog): + mock_manifests = mock.MagicMock() + mock_manifests.config = {"storage-class-parameters": "key=val,something"} + sc = CreateStorageClass(mock_manifests, "default") + assert sc._params == {"key": "val"} + error_logs = [rec for rec in caplog.records if rec.levelname == "ERROR"] + assert len(error_logs) == 1, "Expect one error" + assert error_logs[0].message == "Storage class parameter missing '=' separator in 'something'" diff --git a/upstream/update.py b/upstream/update.py index d74894a..dce2191 100755 --- a/upstream/update.py +++ b/upstream/update.py @@ -88,7 +88,7 @@ def __hash__(self) -> int: return hash(self.name) def __eq__(self, other) -> bool: - """Comparible based on its name.""" + """Comparable based on its name.""" return isinstance(other, Release) and self.name == other.name def __lt__(self, other) -> bool: