Validates baymodel volume_driver requests

Instead of allowing any volume_driver value to be accepted by the
baymodel API. When creating baymodel, the patch can limit the
volume_driver value for the different coe.
Kubernetes <=> volume_driver = "cinder"
Swarm <=> volume_driver = "rexray"
Mesos <=> volume_driver = "rexray"

Co-Authored By: Kai Qiang Wu(Kennan)<wkqwu@cn.ibm.com>
Co-Authored By: Ton Ngo<ton@us.ibm.com>

Partially-Implements: blueprint magnum-integrate-with-cinder
Depends-On: I52c97e2b04ac636ddac611e3677c4ea3972220eb
Change-Id: I25f1cd005a39950c47f31a8b925f664909b79ee3
This commit is contained in:
wangqun 2016-01-19 02:40:11 +00:00
parent ca8268f8b9
commit f2629f288c
9 changed files with 96 additions and 4 deletions

View File

@ -302,6 +302,7 @@ class BayModelsController(rest.RestController):
@expose.expose(BayModel, body=BayModel, status_code=201)
@policy.enforce_wsgi("baymodel", "create")
@validation.enforce_network_driver_types_create()
@validation.enforce_volume_driver_types_create()
def post(self, baymodel):
"""Create a new baymodel.

View File

@ -120,6 +120,23 @@ def _enforce_network_driver_types(baymodel):
validator.validate_network_driver(baymodel.network_driver)
def enforce_volume_driver_types_create():
@decorator.decorator
def wrapper(func, *args, **kwargs):
baymodel = args[1]
_enforce_volume_driver_types(baymodel)
return func(*args, **kwargs)
return wrapper
def _enforce_volume_driver_types(baymodel):
validator = Validator.get_coe_validator(baymodel.coe)
if not baymodel.volume_driver:
return
validator.validate_volume_driver(baymodel.volume_driver)
class Validator(object):
validators = {}
@ -166,12 +183,28 @@ class Validator(object):
'allowed_drivers': '/'.join(
cls.allowed_drivers + ['unspecified'])})
@classmethod
def validate_volume_driver(cls, driver):
cls._validate_volume_driver_supported(driver)
@classmethod
def _validate_volume_driver_supported(cls, driver):
"""Confirm that volume driver is supported by Magnum for this COE."""
if driver not in cls.supported_volume_driver:
raise exception.InvalidParameterValue(_(
'Volume driver type %(driver)s is not supported, '
'expecting a %(supported_volume_driver)s volume driver.') % {
'driver': driver,
'supported_volume_driver': '/'.join(
cls.supported_volume_driver + ['unspecified'])})
class K8sValidator(Validator):
supported_drivers = ['flannel']
allowed_drivers = cfg.CONF.baymodel.kubernetes_allowed_network_drivers
default_driver = cfg.CONF.baymodel.kubernetes_default_network_driver
supported_volume_driver = ['cinder']
class SwarmValidator(Validator):
@ -179,6 +212,7 @@ class SwarmValidator(Validator):
supported_drivers = ['docker', 'flannel']
allowed_drivers = cfg.CONF.baymodel.swarm_allowed_network_drivers
default_driver = cfg.CONF.baymodel.swarm_default_network_driver
supported_volume_driver = ['rexray']
class MesosValidator(Validator):
@ -186,3 +220,4 @@ class MesosValidator(Validator):
supported_drivers = ['docker']
allowed_drivers = cfg.CONF.baymodel.mesos_allowed_network_drivers
default_driver = cfg.CONF.baymodel.mesos_default_network_driver
supported_volume_driver = ['rexray']

View File

@ -176,3 +176,11 @@ class BayModelTest(base.BaseMagnumTest):
self.assertRaises(
exceptions.BadRequest,
self.baymodel_client.post_baymodel, gen_model)
@testtools.testcase.attr('negative')
def test_create_baymodel_invalid_volume_driver(self):
gen_model = datagen.baymodel_data_with_valid_keypair_and_image_id()
gen_model.volume_driver = 'invalid_volume_driver'
self.assertRaises(
exceptions.BadRequest,
self.baymodel_client.post_baymodel, gen_model)

View File

@ -38,6 +38,16 @@ def gen_coe_dep_network_driver(coe):
return driver_types[random.randrange(0, len(driver_types))]
def gen_coe_dep_volume_driver(coe):
allowed_driver_types = {
'kubernetes': ['cinder', None],
'swarm': ['rexray', None],
'mesos': ['rexray', None],
}
driver_types = allowed_driver_types[coe]
return driver_types[random.randrange(0, len(driver_types))]
def gen_random_port():
return random_int(49152, 65535)
@ -91,6 +101,7 @@ def baymodel_data(**kwargs):
"coe": "swarm",
"tls_disabled": False,
"network_driver": None,
"volume_driver": None,
"docker_volume_size": 3,
"labels": {},
"fixed_network": "192.168.0.0/24",
@ -175,7 +186,8 @@ def valid_swarm_baymodel():
docker_volume_size=3, cluster_distro=None,
ssh_authorized_key=None, external_network_id="public",
http_proxy=None, https_proxy=None, no_proxy=None,
network_driver=None, labels={}, tls_disabled=False)
network_driver=None, volume_driver=None, labels={},
tls_disabled=False)
def bay_data(name=data_utils.rand_name('bay'),

View File

@ -41,6 +41,7 @@ class TestKubernetesAPIs(BayAPITLSTest):
coe='kubernetes',
tls_disabled=False,
network_driver='flannel',
volume_driver='cinder',
fixed_network='192.168.0.0/24',
)
cls.bay = cls._create_bay('testk8sAPI', cls.baymodel.uuid)

View File

@ -18,7 +18,8 @@ class TestBayModelResource(BayTest):
def test_baymodel_create_and_delete(self):
self._test_baymodel_create_and_delete('test_mesos_baymodel',
network_driver='docker')
network_driver='docker',
volume_driver='rexray')
class TestBayResource(BayTest):
@ -27,5 +28,5 @@ class TestBayResource(BayTest):
def test_bay_create_and_delete(self):
baymodel_uuid = self._test_baymodel_create_and_delete(
'test_mesos_baymodel', delete=False, tls_disabled=True,
network_driver='docker')
network_driver='docker', volume_driver='rexray')
self._test_bay_create_and_delete('test_mesos_bay', baymodel_uuid)

View File

@ -108,6 +108,7 @@ class BaseMagnumClient(base.TestCase):
coe = kwargs.pop('coe', 'kubernetes')
docker_volume_size = kwargs.pop('docker_volume_size', 3)
network_driver = kwargs.pop('network_driver', 'flannel')
volume_driver = kwargs.pop('volume_driver', 'cinder')
labels = kwargs.pop('labels', {"K1": "V1", "K2": "V2"})
tls_disabled = kwargs.pop('tls_disabled', False)
@ -120,6 +121,7 @@ class BaseMagnumClient(base.TestCase):
master_flavor_id=cls.flavor_id,
docker_volume_size=docker_volume_size,
network_driver=network_driver,
volume_driver=volume_driver,
coe=coe,
labels=labels,
tls_disabled=tls_disabled,

View File

@ -33,7 +33,8 @@ class TestBayModelResource(BayTest):
def test_baymodel_create_and_delete(self):
self._test_baymodel_create_and_delete(
'test_swarm_baymodel',
network_driver=None)
network_driver=None,
volume_driver=None)
class TestSwarmAPIs(BayAPITLSTest):
@ -51,6 +52,7 @@ class TestSwarmAPIs(BayAPITLSTest):
coe='swarm',
tls_disabled=False,
network_driver=None,
volume_driver=None,
docker_volume_size=3,
labels={},
fixed_network='192.168.0.0/24',

View File

@ -318,3 +318,33 @@ class TestValidation(base.BaseTestCase):
network_driver_type=driver,
network_driver_config_dict={
'kubernetes_allowed_network_drivers': ['all']})
def _test_enforce_volume_driver_types_create(
self,
volume_driver_type,
coe='kubernetes',
assert_raised=False):
@v.enforce_volume_driver_types_create()
def test(self, baymodel):
pass
baymodel = mock.MagicMock()
baymodel.name = 'test_baymodel'
baymodel.volume_driver = volume_driver_type
baymodel.coe = coe
if assert_raised:
self.assertRaises(exception.InvalidParameterValue,
test, self, baymodel)
else:
test(self, baymodel)
def test_enforce_volume_driver_types_valid_create(self):
self._test_enforce_volume_driver_types_create(
volume_driver_type='cinder')
def test_enforce_volume_driver_types_invalid_create(self):
self._test_enforce_volume_driver_types_create(
volume_driver_type='type',
assert_raised=True)