Implement mandatory configuration parameters

This patchset adds a class attribute that specifies which configuration
parameters are mandatory, setting the charm's status to 'blocked'
if any of them aren't present (and informing which ones are missing).

Change-Id: Ifcaea22a31f6f5af5edacd2ba5a3e901e7a37225
This commit is contained in:
Luciano Lo Giudice 2022-02-10 19:17:53 -03:00
parent ad443c2d8e
commit e3f29ac758
2 changed files with 35 additions and 0 deletions

View File

@ -64,6 +64,8 @@ class OSBaseCharm(CharmBase):
REQUIRED_RELATIONS = [] REQUIRED_RELATIONS = []
MANDATORY_CONFIG = []
def __init__(self, framework): def __init__(self, framework):
super().__init__(framework) super().__init__(framework)
self.custom_status_checks = [] self.custom_status_checks = []
@ -72,6 +74,7 @@ class OSBaseCharm(CharmBase):
self._stored.set_default(series_upgrade=False) self._stored.set_default(series_upgrade=False)
self.framework.observe(self.on.install, self.on_install) self.framework.observe(self.on.install, self.on_install)
self.framework.observe(self.on.update_status, self.on_update_status) self.framework.observe(self.on.update_status, self.on_update_status)
self.framework.observe(self.on.config_changed, self._on_config)
# A charm may not have pause/resume actions if it does not manage a # A charm may not have pause/resume actions if it does not manage a
# daemon. # daemon.
try: try:
@ -234,6 +237,22 @@ class OSBaseCharm(CharmBase):
self._stored.is_paused = False self._stored.is_paused = False
self.update_status() self.update_status()
def on_config(self, event):
"""Main entry point for configuration changes."""
pass
def _on_config(self, event):
missing = []
config = self.framework.model.config
for param in self.MANDATORY_CONFIG:
if param not in config:
missing.append(param)
if missing:
self.unit.status = BlockedStatus(
'Missing option(s): ' + ','.join(missing))
return
self.on_config(event)
def charm_class(cls): def charm_class(cls):
_releases[cls.release] = {'deb': cls} _releases[cls.release] = {'deb': cls}

View File

@ -77,6 +77,9 @@ class OpenStackTestAPICharm(OpenStackTestPlugin1,
else: else:
return ActiveStatus() return ActiveStatus()
def on_config(self, _):
self.unit.status = ActiveStatus()
class CharmTestCase(unittest.TestCase): class CharmTestCase(unittest.TestCase):
@ -150,6 +153,9 @@ class TestOSBaseCharm(CharmTestCase):
description: yet another failure to report description: yet another failure to report
''') ''')
def tearDown(self):
OpenStackTestAPICharm.MANDATORY_CONFIG = []
def test_init(self): def test_init(self):
self.harness.begin() self.harness.begin()
self.assertFalse(self.harness.charm._stored.is_started) self.assertFalse(self.harness.charm._stored.is_started)
@ -352,3 +358,13 @@ class TestOSBaseCharm(CharmTestCase):
'resume', 'resume',
services=['apache2', 'ks-api'], services=['apache2', 'ks-api'],
charm_func=None) charm_func=None)
def test_mandatory_config(self):
OpenStackTestAPICharm.MANDATORY_CONFIG = ['source']
self.harness.begin()
self.harness.update_config({})
self.assertTrue(
isinstance(self.harness.charm.unit.status, BlockedStatus))
self.harness.update_config({'source': 'value'})
self.assertTrue(
isinstance(self.harness.charm.unit.status, ActiveStatus))