Handle missing/invalid mandatory options
Change-Id: I54d8989bfb374a1fa07dfc145428e546d3839264
diff --git a/src/charm.py b/src/charm.py
index d40d3b3..7c260c7 100755
--- a/src/charm.py
+++ b/src/charm.py
@@ -14,10 +14,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import logging
from ops_openstack.plugins.classes import CinderStoragePluginCharm
from ops_openstack.core import charm_class, get_charm_class
from ops.main import main
+from ops.model import BlockedStatus
+
+logger = logging.getLogger(__name__)
class CinderCharmBase(CinderStoragePluginCharm):
@@ -31,10 +35,44 @@
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
+ def _check_for_config_errors(self, config):
+ missing = []
+ for mandatory in self.MANDATORY_CONFIG:
+ if mandatory not in config:
+ missing.append(mandatory)
+
+ if missing:
+ return f"Mandatory options are missing: {', '.join(missing)}"
+
+ if config["protocol"] not in ["block", "iscsi"]:
+ return (
+ f"""Invalid 'protocol' option provided: '{config["protocol"]}';"""
+ "valid are 'block' and 'iscsi'"
+ )
+
+ if config["protocol"] == "block":
+ return "'protocol' value 'block' not yet supported"
+
+ def on_config(self, event):
+ config = dict(self.framework.model.config)
+ conf_error = self._check_for_config_errors(config)
+ if conf_error is not None:
+ logger.error(conf_error)
+ self.unit.status = BlockedStatus(conf_error)
+ return
+
+ super().on_config(event)
+
def cinder_configuration(self, config):
+ conf_error = self._check_for_config_errors(config)
+ if conf_error is not None:
+ logger.error(conf_error)
+ return []
+
# Return the configuration to be set by the principal.
backend_name = config.get("volume-backend-name", self.framework.model.app.name)
volume_driver = "cinder.volume.drivers.storpool.StorPoolDriver"
+
options = [
("volume_driver", volume_driver),
("volume_backend_name", backend_name),
diff --git a/unit_tests/test_cinder_storpool_charm.py b/unit_tests/test_cinder_storpool_charm.py
index 2399857..78111d8 100644
--- a/unit_tests/test_cinder_storpool_charm.py
+++ b/unit_tests/test_cinder_storpool_charm.py
@@ -14,7 +14,7 @@
import unittest
from src.charm import CinderCharmBase
-from ops.model import ActiveStatus
+from ops.model import ActiveStatus, BlockedStatus
from ops.testing import Harness
@@ -41,6 +41,19 @@
self.assertTrue(conf.get("use_multipath_for_image_xfer"))
self.assertTrue(conf.get("enforce_multipath_for_image_xfer"))
- def test_cinder_configuration(self):
- # Add check here that configuration is as expected.
- pass
+ def test_invalid_cinder_configurations(self):
+ self.harness.update_config({"protocol": "block"})
+ self.assertTrue(isinstance(self.harness.model.unit.status, BlockedStatus))
+
+ self.harness.update_config({"protocol": "iscsi"})
+ self.assertTrue(isinstance(self.harness.model.unit.status, ActiveStatus))
+
+ self.harness.update_config({"protocol": "something_invalid"})
+ self.assertTrue(isinstance(self.harness.model.unit.status, BlockedStatus))
+
+ self.harness.update_config({"protocol": "iscsi"})
+ self.assertTrue(isinstance(self.harness.model.unit.status, ActiveStatus))
+
+ # Cannot test for missing options with default values as it seems the
+ # defaults are applied after update_config() below:
+ # self.harness.update_config(unset=["protocol"])