Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LBaaS and Service-VM code from nsao-neutron-havana #30

Open
wants to merge 3 commits into
base: cis-havana
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions neutron/api/v2/attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,51 @@ def _validate_dict_or_nodata(data, key_specs=None):
if data:
return _validate_dict(data, key_specs)

def _validate_list_item(validator, item):
# Find validator function
val_func = val_params = None
for (k, v) in validator.iteritems():
if k.startswith('type:'):
# ask forgiveness, not permission
try:
val_func = validators[k]
except KeyError:
return _("Validator '%s' does not exist.") % k
val_params = v
break
# Process validation
if val_func:
return val_func(item, val_params)


def _validate_list(data, key_specs=None):
if not isinstance(data, list):
msg = _("'%s' is not a list") % data
LOG.debug(msg)
return msg
# Do not perform any further validation, if no constraints are supplied
if not key_specs:
return

# In case when list is a list of primitives and values should be converted
# replace the items with converted items inside the original list
conv_func = key_specs.get('convert_to')
if (len(data) > 0 and not
(isinstance(data[0], list) or (isinstance(data[0], dict))) and
conv_func):
for index in range(0, len(data)):
data[index] = conv_func(data[index])

for item in data:
msg = _validate_list_item(key_specs, item)
if msg:
return msg
def _validate_list_or_empty(data, key_specs=None):
if data != []:
return _validate_list(data, key_specs)




def _validate_non_negative(data, valid_values=None):
try:
Expand Down Expand Up @@ -510,6 +555,8 @@ def convert_to_list(data):
'type:dict_or_none': _validate_dict_or_none,
'type:dict_or_empty': _validate_dict_or_empty,
'type:dict_or_nodata': _validate_dict_or_nodata,
'type:list': _validate_list,
'type:list_or_empty': _validate_list_or_empty,
'type:fixed_ips': _validate_fixed_ips,
'type:hostroutes': _validate_hostroutes,
'type:ip_address': _validate_ip_address,
Expand Down
101 changes: 101 additions & 0 deletions neutron/api/v2/resource_helper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# (c) Copyright 2014 Cisco Systems Inc.
# All Rights Reserved.
#
# 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.
# @author: Paul Michali Cisco Systems, Inc.

from oslo.config import cfg

from neutron.api import extensions
from neutron.api.v2 import attributes
from neutron.api.v2 import base
from neutron import manager
from neutron.plugins.common import constants
from neutron import quota


def build_plural_mappings(special_mappings, resource_map):
"""Create plural to singular mapping for all resources.

Allows for special mappings to be provided, like policies -> policy.
Otherwise, will strip off the last character for normal mappings, like
routers -> router.
"""
plural_mappings = {}
for plural in resource_map:
singular = special_mappings.get(plural, plural[:-1])
plural_mappings[plural] = singular
return plural_mappings


def build_resource_info(plural_mappings, resource_map, which_service,
ext_plugin=None, action_map=None, register_quota=False,
translate_name=False, allow_bulk=False):
"""Build resources for advanced services.

Takes the resource information, and singular/plural mappings, and creates
API resource objects for advanced services extensions. Will optionally
translate underscores to dashes in resource names, register the resource,
and accept action information for resources.

:param plural_mappings: mappings between singular and plural forms
:param resource_map: attribute map for the WSGI resources to create
:param which_service: The name of the service for which the WSGI resources
are being created. This name will be used to pass
the appropriate plugin to the WSGI resource.
It can be set to None or "CORE"to create WSGI
resources for the the core plugin
:param action_map: custom resource actions
:param register_quota: it can be set to True to register quotas for the
resource(s) being created
:param translate_name: replaces underscores with dashes
:param allow_bulk: True if bulk create are allowed
"""
resources = []
if not which_service:
which_service = constants.CORE
if action_map is None:
action_map = {}

if ext_plugin:
plugin = ext_plugin
elif which_service != constants.CORE:
plugin = manager.NeutronManager.get_service_plugins()[which_service]
else:
plugin = manager.NeutronManager.get_plugin()
for collection_name in resource_map:
resource_name = plural_mappings[collection_name]
params = resource_map.get(collection_name, {})
extended_params = attributes.RESOURCE_ATTRIBUTE_MAP.get(
collection_name)
if (extended_params):
params = extended_params
if translate_name:
collection_name = collection_name.replace('_', '-')
if register_quota:
quota.QUOTAS.register_resource_by_name(resource_name)
member_actions = action_map.get(resource_name, {})
controller = base.create_resource(
collection_name, resource_name, plugin, params,
member_actions=member_actions,
allow_bulk=allow_bulk,
allow_pagination=cfg.CONF.allow_pagination,
allow_sorting=cfg.CONF.allow_sorting)
resource = extensions.ResourceExtension(
collection_name,
controller,
path_prefix=constants.COMMON_PREFIXES[which_service],
member_actions=member_actions,
attr_map=params)
resources.append(resource)
return resources
81 changes: 81 additions & 0 deletions neutron/common/driver_manager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2013, 2014 Intel Corporation.
# Copyright 2013, 2014 Isaku Yamahata <isaku.yamahata at intel com>
# <isaku.yamahata at gmail com>
# All Rights Reserved.
#
#
# 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.
#
# @author: Isaku Yamahata, Intel Corporation.

import logging as log

import stevedore.named

LOG = log.getLogger(__name__)


class DriverManager(object):
def __init__(self, namespace, driver_list, **kwargs):
super(DriverManager, self).__init__()
manager = stevedore.named.NamedExtensionManager(
namespace, driver_list, invoke_on_load=True, **kwargs)

drivers = {}
for ext in manager:
type_ = ext.obj.get_type()
if type_ in drivers:
msg = _("driver '%(new_driver)s' ignored because "
"driver '%(old_driver)s' is already "
"registered for driver '%(type)s'") % {
'new_driver': ext.name,
'old_driver': drivers[type].name,
'type': type_}
LOG.error(msg)
raise SystemExit(msg)
drivers[type_] = ext

self._drivers = dict((type_, ext.obj)
for (type_, ext) in drivers.items())
LOG.info(_("Registered drivers from %(namespace)s: %(keys)s"),
{'namespace': namespace, 'keys': self._drivers.keys()})

@staticmethod
def _driver_name(driver):
return driver.__module__ + '.' + driver.__class__.__name__

def register(self, type_, driver):
if type_ in self._drivers:
new_driver = self._driver_name(driver)
old_driver = self._driver_name(self._drivers[type_])
msg = _("can't load driver '%(new_driver)s' because "
"driver '%(old_driver)s' is already "
"registered for driver '%(type)s'") % {
'new_driver': new_driver,
'old_driver': old_driver,
'type': type_}
LOG.error(msg)
raise SystemExit(msg)
self._drivers[type_] = driver

def invoke(self, type_, method_name, **kwargs):
driver = self._drivers[type_]
return getattr(driver, method_name)(**kwargs)

def __getitem__(self, type_):
return self._drivers[type_]

def __contains__(self, type_):
return type_ in self._drivers
5 changes: 5 additions & 0 deletions neutron/common/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,3 +310,8 @@ class DeviceIDNotOwnedByTenant(Conflict):

class InvalidCIDR(BadRequest):
message = _("Invalid CIDR %(input)s given as IP prefix")


class ExtensionNotSupportedByProvider(NeutronException):
message = _("Extension %(extension_name)s is not supported by "
" %(provider_name)s provider")
6 changes: 6 additions & 0 deletions neutron/db/db_base_plugin_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,12 @@ def _get_marker_obj(self, context, resource, limit, marker):
return getattr(self, '_get_%s' % resource)(context, marker)
return None

@classmethod
def register_dict_extend_funcs(cls, resource, funcs):
cur_funcs = cls._dict_extend_functions.get(resource, [])
cur_funcs.extend(funcs)
cls._dict_extend_functions[resource] = cur_funcs


class NeutronDbPluginV2(neutron_plugin_base_v2.NeutronPluginBaseV2,
CommonDbMixin):
Expand Down
Loading