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:
parent
ca8268f8b9
commit
f2629f288c
|
@ -302,6 +302,7 @@ class BayModelsController(rest.RestController):
|
||||||
@expose.expose(BayModel, body=BayModel, status_code=201)
|
@expose.expose(BayModel, body=BayModel, status_code=201)
|
||||||
@policy.enforce_wsgi("baymodel", "create")
|
@policy.enforce_wsgi("baymodel", "create")
|
||||||
@validation.enforce_network_driver_types_create()
|
@validation.enforce_network_driver_types_create()
|
||||||
|
@validation.enforce_volume_driver_types_create()
|
||||||
def post(self, baymodel):
|
def post(self, baymodel):
|
||||||
"""Create a new baymodel.
|
"""Create a new baymodel.
|
||||||
|
|
||||||
|
|
|
@ -120,6 +120,23 @@ def _enforce_network_driver_types(baymodel):
|
||||||
validator.validate_network_driver(baymodel.network_driver)
|
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):
|
class Validator(object):
|
||||||
|
|
||||||
validators = {}
|
validators = {}
|
||||||
|
@ -166,12 +183,28 @@ class Validator(object):
|
||||||
'allowed_drivers': '/'.join(
|
'allowed_drivers': '/'.join(
|
||||||
cls.allowed_drivers + ['unspecified'])})
|
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):
|
class K8sValidator(Validator):
|
||||||
|
|
||||||
supported_drivers = ['flannel']
|
supported_drivers = ['flannel']
|
||||||
allowed_drivers = cfg.CONF.baymodel.kubernetes_allowed_network_drivers
|
allowed_drivers = cfg.CONF.baymodel.kubernetes_allowed_network_drivers
|
||||||
default_driver = cfg.CONF.baymodel.kubernetes_default_network_driver
|
default_driver = cfg.CONF.baymodel.kubernetes_default_network_driver
|
||||||
|
supported_volume_driver = ['cinder']
|
||||||
|
|
||||||
|
|
||||||
class SwarmValidator(Validator):
|
class SwarmValidator(Validator):
|
||||||
|
@ -179,6 +212,7 @@ class SwarmValidator(Validator):
|
||||||
supported_drivers = ['docker', 'flannel']
|
supported_drivers = ['docker', 'flannel']
|
||||||
allowed_drivers = cfg.CONF.baymodel.swarm_allowed_network_drivers
|
allowed_drivers = cfg.CONF.baymodel.swarm_allowed_network_drivers
|
||||||
default_driver = cfg.CONF.baymodel.swarm_default_network_driver
|
default_driver = cfg.CONF.baymodel.swarm_default_network_driver
|
||||||
|
supported_volume_driver = ['rexray']
|
||||||
|
|
||||||
|
|
||||||
class MesosValidator(Validator):
|
class MesosValidator(Validator):
|
||||||
|
@ -186,3 +220,4 @@ class MesosValidator(Validator):
|
||||||
supported_drivers = ['docker']
|
supported_drivers = ['docker']
|
||||||
allowed_drivers = cfg.CONF.baymodel.mesos_allowed_network_drivers
|
allowed_drivers = cfg.CONF.baymodel.mesos_allowed_network_drivers
|
||||||
default_driver = cfg.CONF.baymodel.mesos_default_network_driver
|
default_driver = cfg.CONF.baymodel.mesos_default_network_driver
|
||||||
|
supported_volume_driver = ['rexray']
|
||||||
|
|
|
@ -176,3 +176,11 @@ class BayModelTest(base.BaseMagnumTest):
|
||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
exceptions.BadRequest,
|
exceptions.BadRequest,
|
||||||
self.baymodel_client.post_baymodel, gen_model)
|
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)
|
||||||
|
|
|
@ -38,6 +38,16 @@ def gen_coe_dep_network_driver(coe):
|
||||||
return driver_types[random.randrange(0, len(driver_types))]
|
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():
|
def gen_random_port():
|
||||||
return random_int(49152, 65535)
|
return random_int(49152, 65535)
|
||||||
|
|
||||||
|
@ -91,6 +101,7 @@ def baymodel_data(**kwargs):
|
||||||
"coe": "swarm",
|
"coe": "swarm",
|
||||||
"tls_disabled": False,
|
"tls_disabled": False,
|
||||||
"network_driver": None,
|
"network_driver": None,
|
||||||
|
"volume_driver": None,
|
||||||
"docker_volume_size": 3,
|
"docker_volume_size": 3,
|
||||||
"labels": {},
|
"labels": {},
|
||||||
"fixed_network": "192.168.0.0/24",
|
"fixed_network": "192.168.0.0/24",
|
||||||
|
@ -175,7 +186,8 @@ def valid_swarm_baymodel():
|
||||||
docker_volume_size=3, cluster_distro=None,
|
docker_volume_size=3, cluster_distro=None,
|
||||||
ssh_authorized_key=None, external_network_id="public",
|
ssh_authorized_key=None, external_network_id="public",
|
||||||
http_proxy=None, https_proxy=None, no_proxy=None,
|
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'),
|
def bay_data(name=data_utils.rand_name('bay'),
|
||||||
|
|
|
@ -41,6 +41,7 @@ class TestKubernetesAPIs(BayAPITLSTest):
|
||||||
coe='kubernetes',
|
coe='kubernetes',
|
||||||
tls_disabled=False,
|
tls_disabled=False,
|
||||||
network_driver='flannel',
|
network_driver='flannel',
|
||||||
|
volume_driver='cinder',
|
||||||
fixed_network='192.168.0.0/24',
|
fixed_network='192.168.0.0/24',
|
||||||
)
|
)
|
||||||
cls.bay = cls._create_bay('testk8sAPI', cls.baymodel.uuid)
|
cls.bay = cls._create_bay('testk8sAPI', cls.baymodel.uuid)
|
||||||
|
|
|
@ -18,7 +18,8 @@ class TestBayModelResource(BayTest):
|
||||||
|
|
||||||
def test_baymodel_create_and_delete(self):
|
def test_baymodel_create_and_delete(self):
|
||||||
self._test_baymodel_create_and_delete('test_mesos_baymodel',
|
self._test_baymodel_create_and_delete('test_mesos_baymodel',
|
||||||
network_driver='docker')
|
network_driver='docker',
|
||||||
|
volume_driver='rexray')
|
||||||
|
|
||||||
|
|
||||||
class TestBayResource(BayTest):
|
class TestBayResource(BayTest):
|
||||||
|
@ -27,5 +28,5 @@ class TestBayResource(BayTest):
|
||||||
def test_bay_create_and_delete(self):
|
def test_bay_create_and_delete(self):
|
||||||
baymodel_uuid = self._test_baymodel_create_and_delete(
|
baymodel_uuid = self._test_baymodel_create_and_delete(
|
||||||
'test_mesos_baymodel', delete=False, tls_disabled=True,
|
'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)
|
self._test_bay_create_and_delete('test_mesos_bay', baymodel_uuid)
|
||||||
|
|
|
@ -108,6 +108,7 @@ class BaseMagnumClient(base.TestCase):
|
||||||
coe = kwargs.pop('coe', 'kubernetes')
|
coe = kwargs.pop('coe', 'kubernetes')
|
||||||
docker_volume_size = kwargs.pop('docker_volume_size', 3)
|
docker_volume_size = kwargs.pop('docker_volume_size', 3)
|
||||||
network_driver = kwargs.pop('network_driver', 'flannel')
|
network_driver = kwargs.pop('network_driver', 'flannel')
|
||||||
|
volume_driver = kwargs.pop('volume_driver', 'cinder')
|
||||||
labels = kwargs.pop('labels', {"K1": "V1", "K2": "V2"})
|
labels = kwargs.pop('labels', {"K1": "V1", "K2": "V2"})
|
||||||
tls_disabled = kwargs.pop('tls_disabled', False)
|
tls_disabled = kwargs.pop('tls_disabled', False)
|
||||||
|
|
||||||
|
@ -120,6 +121,7 @@ class BaseMagnumClient(base.TestCase):
|
||||||
master_flavor_id=cls.flavor_id,
|
master_flavor_id=cls.flavor_id,
|
||||||
docker_volume_size=docker_volume_size,
|
docker_volume_size=docker_volume_size,
|
||||||
network_driver=network_driver,
|
network_driver=network_driver,
|
||||||
|
volume_driver=volume_driver,
|
||||||
coe=coe,
|
coe=coe,
|
||||||
labels=labels,
|
labels=labels,
|
||||||
tls_disabled=tls_disabled,
|
tls_disabled=tls_disabled,
|
||||||
|
|
|
@ -33,7 +33,8 @@ class TestBayModelResource(BayTest):
|
||||||
def test_baymodel_create_and_delete(self):
|
def test_baymodel_create_and_delete(self):
|
||||||
self._test_baymodel_create_and_delete(
|
self._test_baymodel_create_and_delete(
|
||||||
'test_swarm_baymodel',
|
'test_swarm_baymodel',
|
||||||
network_driver=None)
|
network_driver=None,
|
||||||
|
volume_driver=None)
|
||||||
|
|
||||||
|
|
||||||
class TestSwarmAPIs(BayAPITLSTest):
|
class TestSwarmAPIs(BayAPITLSTest):
|
||||||
|
@ -51,6 +52,7 @@ class TestSwarmAPIs(BayAPITLSTest):
|
||||||
coe='swarm',
|
coe='swarm',
|
||||||
tls_disabled=False,
|
tls_disabled=False,
|
||||||
network_driver=None,
|
network_driver=None,
|
||||||
|
volume_driver=None,
|
||||||
docker_volume_size=3,
|
docker_volume_size=3,
|
||||||
labels={},
|
labels={},
|
||||||
fixed_network='192.168.0.0/24',
|
fixed_network='192.168.0.0/24',
|
||||||
|
|
|
@ -318,3 +318,33 @@ class TestValidation(base.BaseTestCase):
|
||||||
network_driver_type=driver,
|
network_driver_type=driver,
|
||||||
network_driver_config_dict={
|
network_driver_config_dict={
|
||||||
'kubernetes_allowed_network_drivers': ['all']})
|
'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)
|
||||||
|
|
Loading…
Reference in New Issue