Don't create clusters of an unsupported type

Return a 400 error if the cluster type is unsupported (ie. no drivers
are installed that will create a cluster of that particular server
type, cluster distro, and COE combination).

Partial-Bug: #1646215
Change-Id: I26d9881cfc530132e1aa88d01194c6496bc527f4
This commit is contained in:
Jason Dunsmore 2017-01-25 11:36:22 -06:00
parent 2e521c2ebc
commit 54d38f40bb
4 changed files with 71 additions and 3 deletions

View File

@ -28,7 +28,7 @@ from magnum.api.controllers.v1 import collection
from magnum.api.controllers.v1 import types
from magnum.api import expose
from magnum.api import utils as api_utils
from magnum.api.validation import validate_cluster_properties
from magnum.api import validation
from magnum.common import clients
from magnum.common import exception
from magnum.common import name_generator
@ -375,6 +375,7 @@ class ClustersController(base.Controller):
raise exception.ResourceLimitExceeded(msg=msg)
@expose.expose(ClusterID, body=Cluster, status_code=202)
@validation.enforce_cluster_type_supported()
def post(self, cluster):
"""Create a new cluster.
@ -473,7 +474,7 @@ class ClustersController(base.Controller):
delta = cluster.obj_what_changed()
validate_cluster_properties(delta)
validation.validate_cluster_properties(delta)
return cluster
@expose.expose(None, types.uuid_or_name, status_code=204)

View File

@ -20,6 +20,7 @@ import pecan
from magnum.api import utils as api_utils
from magnum.common import exception
import magnum.conf
from magnum.drivers.common import driver
from magnum.i18n import _
from magnum import objects
@ -28,6 +29,21 @@ CONF = magnum.conf.CONF
cluster_update_allowed_properties = set(['node_count'])
def enforce_cluster_type_supported():
@decorator.decorator
def wrapper(func, *args, **kwargs):
cluster = args[1]
cluster_template = objects.ClusterTemplate.get_by_uuid(
pecan.request.context, cluster.cluster_template_id)
cluster_type = (cluster_template.server_type,
cluster_template.cluster_distro,
cluster_template.coe)
driver.Driver.get_driver(*cluster_type)
return func(*args, **kwargs)
return wrapper
def enforce_network_driver_types_create():
@decorator.decorator
def wrapper(func, *args, **kwargs):

View File

@ -260,7 +260,7 @@ class NotSupported(MagnumException):
code = 400
class ClusterTypeNotSupported(MagnumException):
class ClusterTypeNotSupported(NotSupported):
message = _("Cluster type (%(server_type)s, %(os)s, %(coe)s)"
" not supported.")

View File

@ -28,6 +28,57 @@ CONF = magnum.conf.CONF
class TestValidation(base.BaseTestCase):
def _test_enforce_cluster_type_supported(
self, mock_cluster_template_get_by_uuid, mock_cluster_get_by_uuid,
mock_pecan_request, cluster_type, assert_raised=False):
@v.enforce_cluster_type_supported()
def test(self, cluster):
pass
server_type, cluster_distro, coe = cluster_type
cluster_template = obj_utils.get_test_cluster_template(
mock_pecan_request.context, uuid='cluster_template_id',
coe=coe, cluster_distro=cluster_distro, server_type=server_type)
mock_cluster_template_get_by_uuid.return_value = cluster_template
cluster = mock.MagicMock()
cluster.cluster_template_id = 'cluster_template_id'
cluster.cluster_template = cluster_template
mock_cluster_get_by_uuid.return_value = cluster
if assert_raised:
return self.assertRaises(
exception.ClusterTypeNotSupported, test, self, cluster)
else:
self.assertIsNone(test(self, cluster))
@mock.patch('pecan.request')
@mock.patch('magnum.objects.Cluster.get_by_uuid')
@mock.patch('magnum.objects.ClusterTemplate.get_by_uuid')
def test_enforce_cluster_type_supported(
self, mock_cluster_template_get_by_uuid, mock_cluster_get_by_uuid,
mock_pecan_request):
cluster_type = ('vm', 'fedora-atomic', 'kubernetes')
self._test_enforce_cluster_type_supported(
mock_cluster_template_get_by_uuid, mock_cluster_get_by_uuid,
mock_pecan_request, cluster_type)
@mock.patch('pecan.request')
@mock.patch('magnum.objects.Cluster.get_by_uuid')
@mock.patch('magnum.objects.ClusterTemplate.get_by_uuid')
def test_enforce_cluster_type_not_supported(
self, mock_cluster_template_get_by_uuid, mock_cluster_get_by_uuid,
mock_pecan_request):
cluster_type = ('vm', 'foo', 'kubernetes')
exc = self._test_enforce_cluster_type_supported(
mock_cluster_template_get_by_uuid, mock_cluster_get_by_uuid,
mock_pecan_request, cluster_type, assert_raised=True)
self.assertEqual('Cluster type (vm, foo, kubernetes) not supported.',
exc.message)
def _test_enforce_network_driver_types_create(
self,
network_driver_type,