Baymodel create should allow no network_driver specified

When a kubernetes baymodel is created, the current API validation
only allows an explicit setting of "flannel" for the network-driver
attribute. This validation needs to be changed to allow a user to
create a kubernetes baymodel without explicitly specifying a
network driver. (The same goes for docker swarm and mesos baymodels,
that is, baymodel create should allow the user not to specify
a network-driver, but this is the current behavior).

When no network-driver is selected for baymodel create for a
given COE, Magnum should choose the default network driver for that
COE. Note that this change set only handles the validation for
the case where no network-driver is selected; mapping this to
the COE-dependent default network driver will be done in other
commits (e.g. https://review.openstack.org/#/c/224367/ for swarm).

Note that no new unit test cases were added for this patch since
test_create_baymodel_with_network_driver and
test_create_baymodel_with_no_network_driver test cases in
test_baymodel.py should cover this change.

Change-Id: I0735f79354bc9fdb141e7a559517268e8ab648ec
Closes-Bug: 1501077
This commit is contained in:
Dane LeBlanc 2015-10-01 16:44:45 -04:00 committed by Daneyon Hansen
parent 98f915ac9d
commit fd2e760541
6 changed files with 36 additions and 14 deletions

View File

@ -216,6 +216,16 @@ class BayModelsController(rest.RestController):
'detail': ['GET'],
}
# Allowed network driver types per COE. An entry of None in this
# dictionary allows the user to leave out the selection of
# network-driver, in which case the default network driver for
# the chosen COE will be used.
_allowed_network_driver_types = {
'kubernetes': ['flannel', None],
'swarm': [None],
'mesos': [None],
}
def _get_baymodels_collection(self, marker, limit,
sort_key, sort_dir, expand=False,
resource_url=None):
@ -312,7 +322,7 @@ class BayModelsController(rest.RestController):
@policy.enforce_wsgi("baymodel", "create")
@expose.expose(BayModel, body=BayModel, status_code=201)
@validation.enforce_network_driver_types(kubernetes=['flannel'])
@validation.enforce_network_driver_types(_allowed_network_driver_types)
def post(self, baymodel):
"""Create a new baymodel.
@ -345,7 +355,7 @@ class BayModelsController(rest.RestController):
@policy.enforce_wsgi("baymodel", "update")
@wsme.validate(types.uuid, [BayModelPatchType])
@expose.expose(BayModel, types.uuid, body=[BayModelPatchType])
@validation.enforce_network_driver_types(kubernetes=['flannel'])
@validation.enforce_network_driver_types(_allowed_network_driver_types)
def patch(self, baymodel_uuid, patch):
"""Update an existing baymodel.

View File

@ -39,7 +39,7 @@ def enforce_bay_types(*bay_types):
return wrapper
def enforce_network_driver_types(**network_driver_types):
def enforce_network_driver_types(network_driver_types_dict):
@decorator.decorator
def wrapper(func, *args, **kwargs):
obj = args[1]
@ -53,16 +53,17 @@ def enforce_network_driver_types(**network_driver_types):
obj)
driver = baymodel.network_driver
coe = baymodel.coe
if (coe in network_driver_types and
driver not in network_driver_types[coe]):
if (coe in network_driver_types_dict and
driver not in network_driver_types_dict[coe]):
raise exception.InvalidParameterValue(
'Cannot fulfill request with a '
'%(network_driver_type)s network_driver, '
'expecting a %(supported_network_driver_types)s '
'network_driver.' %
{'network_driver_type': driver,
'supported_network_driver_types': '/'
.join(network_driver_types)})
'supported_network_driver_types':
'/'.join([x if x else 'unspecified' for x in
network_driver_types_dict[coe]])})
return func(*args, **kwargs)

View File

@ -46,6 +46,16 @@ def generate_random_coe():
return coe_list[random.randrange(0, len(coe_list))]
def generate_random_coe_dep_network_driver(coe):
allowed_driver_types = {
'kubernetes': ['flannel', None],
'swarm': [None],
'mesos': [None],
}
driver_types = allowed_driver_types[coe]
return driver_types[random.randrange(0, len(driver_types))]
def generate_random_port():
return random.randrange(49152, 65535)
@ -78,6 +88,7 @@ def random_baymodel_data(keypair_id=random_string(), image_id=random_string()):
:returns: BayModelEntity with generated data
"""
coe = generate_random_coe()
data = {
"name": random_string(),
"image_id": image_id,
@ -91,11 +102,11 @@ def random_baymodel_data(keypair_id=random_string(), image_id=random_string()):
"docker_volume_size": generate_random_docker_volume_size(),
"cluster_distro": random_string(),
"ssh_authorized_key": generate_fake_ssh_pubkey(),
"coe": generate_random_coe(),
"coe": coe,
"http_proxy": "http://proxy.com:%s" % generate_random_port(),
"https_proxy": "https://proxy.com:%s" % generate_random_port(),
"no_proxy": ",".join(generate_random_ip() for x in range(3)),
"network_driver": "flannel",
"network_driver": generate_random_coe_dep_network_driver(coe),
"labels": {"K1": "V1", "K2": "V2"},
}
model = baymodel_model.BayModelEntity.from_dict(data)

View File

@ -238,7 +238,6 @@ class TestPatch(api_base.FunctionalTest):
image_id='nerdherd',
apiserver_port=8080,
fixed_network='private',
network_driver='flannel',
public=False,
docker_volume_size=20,
ssh_authorized_key='ssh-rsa AAAAB3NzaC1ycEAAAADA'
@ -620,7 +619,8 @@ class TestPost(api_base.FunctionalTest):
mock_keypair_exists.return_value = None
mock_image_data.return_value = {'name': 'mock_name',
'os_distro': 'fedora-atomic'}
bdict = apiutils.baymodel_post_data(network_driver='flannel')
bdict = apiutils.baymodel_post_data(coe='kubernetes',
network_driver='flannel')
response = self.post_json('/baymodels', bdict)
self.assertEqual(bdict['network_driver'],
response.json['network_driver'])

View File

@ -108,7 +108,7 @@ class TestValidation(base.BaseTestCase):
allowed_network_driver_types,
assert_raised=False):
@v.enforce_network_driver_types(**allowed_network_driver_types)
@v.enforce_network_driver_types(allowed_network_driver_types)
def test(self, baymodel):
pass
@ -148,7 +148,7 @@ class TestValidation(base.BaseTestCase):
allowed_network_driver_types,
assert_raised=False):
@v.enforce_network_driver_types(**allowed_network_driver_types)
@v.enforce_network_driver_types(allowed_network_driver_types)
def test(self, baymodel_uuid):
pass

View File

@ -32,7 +32,7 @@ def get_test_baymodel(**kw):
'external_network_id': kw.get('external_network_id',
'd1f02cfb-d27f-4068-9332-84d907cb0e2e'),
'fixed_network': kw.get('fixed_network', 'private'),
'network_driver': kw.get('network_driver', 'flannel'),
'network_driver': kw.get('network_driver'),
'dns_nameserver': kw.get('dns_nameserver', '8.8.1.1'),
'apiserver_port': kw.get('apiserver_port', 8080),
'docker_volume_size': kw.get('docker_volume_size', 20),