224 lines
8.3 KiB
Python
224 lines
8.3 KiB
Python
# Copyright 2015 Huawei Technologies Co.,LTD.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
# implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
import decorator
|
|
from oslo_config import cfg
|
|
import pecan
|
|
|
|
from magnum.api import utils as api_utils
|
|
from magnum.common import exception
|
|
from magnum.common import utils
|
|
from magnum.i18n import _
|
|
from magnum import objects
|
|
|
|
|
|
baymodel_opts = [
|
|
cfg.ListOpt('kubernetes_allowed_network_drivers',
|
|
default=['all'],
|
|
help=_("Allowed network drivers for kubernetes baymodels. "
|
|
"Use 'all' keyword to allow all drivers supported "
|
|
"for kubernetes baymodels. Supported network drivers "
|
|
"include flannel.")),
|
|
cfg.StrOpt('kubernetes_default_network_driver',
|
|
default='flannel',
|
|
help=_("Default network driver for kubernetes baymodels.")),
|
|
cfg.ListOpt('swarm_allowed_network_drivers',
|
|
default=['all'],
|
|
help=_("Allowed network drivers for docker swarm baymodels. "
|
|
"Use 'all' keyword to allow all drivers supported "
|
|
"for swarm baymodels. Supported network drivers "
|
|
"include docker and flannel.")),
|
|
cfg.StrOpt('swarm_default_network_driver',
|
|
default='docker',
|
|
help=_("Default network driver for docker swarm baymodels.")),
|
|
cfg.ListOpt('mesos_allowed_network_drivers',
|
|
default=['all'],
|
|
help=_("Allowed network drivers for mesos baymodels. "
|
|
"Use 'all' keyword to allow all drivers supported "
|
|
"for mesos baymodels. Supported network drivers "
|
|
"include docker.")),
|
|
cfg.StrOpt('mesos_default_network_driver',
|
|
default='docker',
|
|
help=_("Default network driver for mesos baymodels.")),
|
|
]
|
|
cfg.CONF.register_opts(baymodel_opts, group='baymodel')
|
|
|
|
|
|
def enforce_bay_types(*bay_types):
|
|
"""Enforce that bay_type is in supported list."""
|
|
@decorator.decorator
|
|
def wrapper(func, *args, **kwargs):
|
|
# Note(eliqiao): This decorator has some assumptions
|
|
# args[1] should be an APIBase instance or
|
|
# args[2] should be a bay_ident
|
|
obj = args[1]
|
|
if hasattr(obj, 'bay_uuid'):
|
|
bay = objects.Bay.get_by_uuid(pecan.request.context, obj.bay_uuid)
|
|
else:
|
|
bay_ident = args[2]
|
|
if utils.is_uuid_like(bay_ident):
|
|
bay = objects.Bay.get_by_uuid(pecan.request.context, bay_ident)
|
|
else:
|
|
bay = objects.Bay.get_by_name(pecan.request.context, bay_ident)
|
|
|
|
if bay.baymodel.coe not in bay_types:
|
|
raise exception.InvalidParameterValue(_(
|
|
'Cannot fulfill request with a %(bay_type)s bay, '
|
|
'expecting a %(supported_bay_types)s bay.') %
|
|
{'bay_type': bay.baymodel.coe,
|
|
'supported_bay_types': '/'.join(bay_types)})
|
|
|
|
return func(*args, **kwargs)
|
|
|
|
return wrapper
|
|
|
|
|
|
def enforce_network_driver_types_create():
|
|
@decorator.decorator
|
|
def wrapper(func, *args, **kwargs):
|
|
baymodel = args[1]
|
|
_enforce_network_driver_types(baymodel)
|
|
return func(*args, **kwargs)
|
|
|
|
return wrapper
|
|
|
|
|
|
def enforce_network_driver_types_update():
|
|
@decorator.decorator
|
|
def wrapper(func, *args, **kwargs):
|
|
baymodel_ident = args[1]
|
|
patch = args[2]
|
|
baymodel = api_utils.get_rpc_resource('BayModel', baymodel_ident)
|
|
try:
|
|
baymodel_dict = api_utils.apply_jsonpatch(baymodel.as_dict(),
|
|
patch)
|
|
except api_utils.JSONPATCH_EXCEPTIONS as e:
|
|
raise exception.PatchError(patch=patch, reason=e)
|
|
baymodel = objects.BayModel(pecan.request.context, **baymodel_dict)
|
|
_enforce_network_driver_types(baymodel)
|
|
return func(*args, **kwargs)
|
|
|
|
return wrapper
|
|
|
|
|
|
def _enforce_network_driver_types(baymodel):
|
|
validator = Validator.get_coe_validator(baymodel.coe)
|
|
if not baymodel.network_driver:
|
|
baymodel.network_driver = validator.default_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):
|
|
|
|
validators = {}
|
|
|
|
@classmethod
|
|
def get_coe_validator(cls, coe):
|
|
if not cls.validators:
|
|
cls.validators = {
|
|
'kubernetes': K8sValidator(),
|
|
'swarm': SwarmValidator(),
|
|
'mesos': MesosValidator(),
|
|
}
|
|
if coe in cls.validators:
|
|
return cls.validators[coe]
|
|
else:
|
|
raise exception.InvalidParameterValue(
|
|
_('Requested COE type %s is not supported.') % coe)
|
|
|
|
@classmethod
|
|
def validate_network_driver(cls, driver):
|
|
cls._validate_network_driver_supported(driver)
|
|
cls._validate_network_driver_allowed(driver)
|
|
|
|
@classmethod
|
|
def _validate_network_driver_supported(cls, driver):
|
|
"""Confirm that driver is supported by Magnum for this COE."""
|
|
if driver not in cls.supported_drivers:
|
|
raise exception.InvalidParameterValue(_(
|
|
'Network driver type %(driver)s is not supported, '
|
|
'expecting a %(supported_drivers)s network driver.') % {
|
|
'driver': driver,
|
|
'supported_drivers': '/'.join(
|
|
cls.supported_drivers + ['unspecified'])})
|
|
|
|
@classmethod
|
|
def _validate_network_driver_allowed(cls, driver):
|
|
"""Confirm that driver is allowed via configuration for this COE."""
|
|
if ('all' not in cls.allowed_drivers and
|
|
driver not in cls.allowed_drivers):
|
|
raise exception.InvalidParameterValue(_(
|
|
'Network driver type %(driver)s is not allowed, '
|
|
'expecting a %(allowed_drivers)s network driver. ') % {
|
|
'driver': driver,
|
|
'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):
|
|
|
|
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):
|
|
|
|
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']
|