From 05c7f35d23adc7a60b4101889465aad0ce1670cf Mon Sep 17 00:00:00 2001 From: Feilong Wang Date: Mon, 5 Feb 2018 22:39:35 +1300 Subject: [PATCH] Add disabled_drivers config option The new config option 'disabled_drivers' is designed to address a typical user case: As cloud provider, I'd like to only provide some particular drivers, e.g. fedora atomic/k8s and don't expose any other driver support. With this patch, when user create a new template which is in 'disabled_drivers'. A BadRequest error will be returned. Closes-Bug: #1746961 Change-Id: Ib4c53ffed78a1847b2da9672e6348c88757ad66e --- magnum/api/controllers/v1/cluster_template.py | 1 + magnum/api/validation.py | 24 +++++++++++++++++++ magnum/conf/drivers.py | 8 ++++++- magnum/drivers/common/driver.py | 3 ++- .../controllers/v1/test_cluster_template.py | 8 +++++++ 5 files changed, 42 insertions(+), 2 deletions(-) diff --git a/magnum/api/controllers/v1/cluster_template.py b/magnum/api/controllers/v1/cluster_template.py index d85c43d4bc..cdc0b9bf49 100644 --- a/magnum/api/controllers/v1/cluster_template.py +++ b/magnum/api/controllers/v1/cluster_template.py @@ -368,6 +368,7 @@ class ClusterTemplatesController(base.Controller): @validation.enforce_network_driver_types_create() @validation.enforce_volume_driver_types_create() @validation.enforce_volume_storage_size_create() + @validation.enforce_driver_supported() def post(self, cluster_template): """Create a new ClusterTemplate. diff --git a/magnum/api/validation.py b/magnum/api/validation.py index 4cc325a12f..6f4f246d2d 100644 --- a/magnum/api/validation.py +++ b/magnum/api/validation.py @@ -48,6 +48,30 @@ def enforce_cluster_type_supported(): return wrapper +def enforce_driver_supported(): + @decorator.decorator + def wrapper(func, *args, **kwargs): + cluster_template = args[1] + cluster_distro = cluster_template.cluster_distro + if not cluster_distro: + try: + cli = clients.OpenStackClients(pecan.request.context) + image_id = cluster_template.image_id + image = api_utils.get_openstack_resource(cli.glance().images, + image_id, + 'images') + cluster_distro = image.get('os_distro') + except Exception: + pass + cluster_type = (cluster_template.server_type, + cluster_distro, + cluster_template.coe) + driver.Driver.get_driver(*cluster_type) + return func(*args, **kwargs) + + return wrapper + + def enforce_cluster_volume_storage_size(): @decorator.decorator def wrapper(func, *args, **kwargs): diff --git a/magnum/conf/drivers.py b/magnum/conf/drivers.py index 674ab02531..e4e32d91ea 100644 --- a/magnum/conf/drivers.py +++ b/magnum/conf/drivers.py @@ -33,7 +33,13 @@ drivers_opts = [ cfg.BoolOpt('send_cluster_metrics', default=True, help='Allow periodic tasks to pull COE data and send to ' - 'ceilometer.') + 'ceilometer.'), + cfg.ListOpt('disabled_drivers', + default=[], + help='Disabled driver entry points. The default value is []. ' + ' Means if not specified, then all available drivers ' + 'are enabled.' + ), ] diff --git a/magnum/drivers/common/driver.py b/magnum/drivers/common/driver.py index d925ee305b..711c2007a4 100644 --- a/magnum/drivers/common/driver.py +++ b/magnum/drivers/common/driver.py @@ -34,7 +34,8 @@ class Driver(object): @classmethod def load_entry_points(cls): for entry_point in iter_entry_points('magnum.drivers'): - yield entry_point, entry_point.load(require=False) + if entry_point.name not in CONF.drivers.disabled_drivers: + yield entry_point, entry_point.load(require=False) @classmethod def get_drivers(cls): diff --git a/magnum/tests/unit/api/controllers/v1/test_cluster_template.py b/magnum/tests/unit/api/controllers/v1/test_cluster_template.py index 5ef612ba9f..46f3311738 100644 --- a/magnum/tests/unit/api/controllers/v1/test_cluster_template.py +++ b/magnum/tests/unit/api/controllers/v1/test_cluster_template.py @@ -1017,6 +1017,14 @@ class TestPost(api_base.FunctionalTest): self.assertEqual(201, resp.status_int) self.assertIsNotNone(resp.json['name']) + def test_create_cluster_with_disabled_driver(self): + cfg.CONF.set_override('disabled_drivers', + ['mesos_ubuntu_v1'], + group='drivers') + bdict = apiutils.cluster_template_post_data(coe="mesos") + self.assertRaises(AppError, self.post_json, '/clustertemplates', + bdict) + class TestDelete(api_base.FunctionalTest):