From 45ffbcd9a45e2164c8d42771cb6df7080da70faf Mon Sep 17 00:00:00 2001 From: Liam Young Date: Sat, 26 Jan 2019 15:30:21 +0000 Subject: [PATCH] Allow charms to specify mandatory_config. Allow a charm to specify config options that must be set. The charm can do this by creating a list of config options called mandatory_config. The check is run everytime assess_status is called. Change-Id: I2bb9d2d873e1916624a26c08b036a16e91195b86 --- charms_openstack/charm/core.py | 23 +++++++++++++++++++ .../charms_openstack/charm/test_core.py | 23 +++++++++++++++++++ unit_tests/charms_openstack/charm/utils.py | 9 +++++++- 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/charms_openstack/charm/core.py b/charms_openstack/charm/core.py index 4328ce2..1edbf54 100644 --- a/charms_openstack/charm/core.py +++ b/charms_openstack/charm/core.py @@ -1088,6 +1088,7 @@ class BaseOpenStackCharmAssessStatus(object): for f in [self.check_if_paused, self.custom_assess_status_check, self.check_interfaces, + self.check_mandatory_config, self.check_services_running]: state, message = f() if state is not None: @@ -1199,6 +1200,28 @@ class BaseOpenStackCharmAssessStatus(object): # Everything is fine. return None, None + def check_mandatory_config(self): + """Check that all mandatory config has been set. + + Returns (None, None) if the interfaces are okay, or a status, message + if any of the config is missing. + + :returns status & message info + :rtype: (status, message) or (None, None) + """ + missing_config = [] + status = None + message = None + if getattr(self, 'mandatory_config', None): + for c in self.mandatory_config: + if hookenv.config(c) is None: + missing_config.append(c) + if missing_config: + status = 'blocked' + message = 'The following mandatory config is unset: {}'.format( + ','.join(missing_config)) + return status, message + def states_to_check(self, required_relations=None): """Construct a default set of connected and available states for each of the relations passed, along with error messages and new status diff --git a/unit_tests/charms_openstack/charm/test_core.py b/unit_tests/charms_openstack/charm/test_core.py index 23e4fe3..544e050 100644 --- a/unit_tests/charms_openstack/charm/test_core.py +++ b/unit_tests/charms_openstack/charm/test_core.py @@ -15,6 +15,9 @@ from unit_tests.charms_openstack.charm.common import ( import unit_tests.utils as utils TEST_CONFIG = {'config': True, + 'mandconfig1': 'Iamset', + 'mandconfig2': 'Iamalsoset', + 'mandconfig3': None, 'openstack-origin': None} SNAP_MAP = { 'mysnap': { @@ -197,6 +200,7 @@ class TestBaseOpenStackCharmAssessStatus(BaseOpenStackCharmTest): # disable all of the check functions self.patch_target('check_if_paused', return_value=(None, None)) self.patch_target('check_interfaces', return_value=(None, None)) + self.patch_target('check_mandatory_config', return_value=(None, None)) self.patch_target('custom_assess_status_check', return_value=(None, None)) self.patch_target('check_services_running', return_value=(None, None)) @@ -210,6 +214,7 @@ class TestBaseOpenStackCharmAssessStatus(BaseOpenStackCharmTest): # check all the check functions got called self.check_if_paused.assert_called_once_with() self.check_interfaces.assert_called_once_with() + self.check_mandatory_config.assert_called_once_with() self.custom_assess_status_check.assert_called_once_with() self.check_services_running.assert_called_once_with() @@ -289,6 +294,24 @@ class TestBaseOpenStackCharmAssessStatus(BaseOpenStackCharmTest): } self.assertEqual(self.target.check_interfaces(), (None, None)) + def test_check_mandatory_config_no_mandatory_config(self): + self.assertEqual( + self.target.check_mandatory_config(), + (None, None)) + + def test_check_mandatory_config_config_set(self): + self.target.mandatory_config = ['mandconfig1', 'mandconfig2'] + self.assertEqual( + self.target.check_mandatory_config(), + (None, None)) + + def test_check_mandatory_config_config_unset(self): + self.target.mandatory_config = ['mandconfig1', 'mandconfig3'] + self.assertEqual( + self.target.check_mandatory_config(), + ('blocked', + 'The following mandatory config is unset: mandconfig3')) + def test_check_assess_status_check_services_running(self): # verify that the function calls _ows_check_services_running() with the # valid information diff --git a/unit_tests/charms_openstack/charm/utils.py b/unit_tests/charms_openstack/charm/utils.py index 348f7b8..0d9561b 100644 --- a/unit_tests/charms_openstack/charm/utils.py +++ b/unit_tests/charms_openstack/charm/utils.py @@ -18,11 +18,18 @@ class BaseOpenStackCharmTest(unit_tests.utils.BaseTestCase): cls.patched_config_started = None cls.patched_config = None + def _get_config(self, x=None): + if x: + return self._test_config.get(x, None) + else: + return self._test_config + def setUp(self, target_cls, test_config): super().setUp() # set up the return value on the mock before instantiating the class to # get the config into the class.config. - chm_core.hookenv.config.return_value = test_config + self._test_config = test_config + chm_core.hookenv.config.side_effect = self._get_config self.target = target_cls() def tearDown(self):