194 lines
7.8 KiB
Python
194 lines
7.8 KiB
Python
# 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 itertools
|
|
|
|
from oslo_log import log as logging
|
|
|
|
from gbpservice.neutron.tests.unit import common as cm
|
|
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
# While plugin APIs support ORing filters, they are not supported in REST APIs
|
|
# or WSGI. A combination of these filters have to be generated to emulate the
|
|
# ORing behavior.
|
|
# For example, filters = {'foo': [a1, a2], 'bar': [b1, b2]} will be mapped to
|
|
# a list of filters
|
|
# [{'foo': a1, 'bar': b1},
|
|
# {'foo': a1, 'bar': b2},
|
|
# {'foo': a2, 'bar': b1},
|
|
# {'foo': a2, 'bar': b2}]
|
|
def get_filter_combinations(filters):
|
|
formatted_filters = {}
|
|
for key, value in filters.iteritems():
|
|
formatted_filters[key] = value if isinstance(value, list) else [value]
|
|
keys = sorted(formatted_filters)
|
|
return [dict(zip(keys, prod)) for prod in
|
|
itertools.product(*(formatted_filters[key] for key in keys))]
|
|
|
|
|
|
class NeutronAPIMixin(object):
|
|
"""A Wrapper class of Neutronv2 Client APIs.
|
|
|
|
Ideally, we want to call Neutronv2 Client APIs directly in resource mapping
|
|
and other drivers. But there are some existing APIs as previously plugin
|
|
APIs were used, and we need to keep these APIs so we don't need to touch
|
|
too many codes. Later when we clean up the resource mappings, this Mixin
|
|
wrapper should be removed as well.
|
|
"""
|
|
|
|
def _create_port(self, plugin_context, attrs):
|
|
return self._create_neutron_resource(plugin_context, 'port', attrs)
|
|
|
|
def _get_port(self, plugin_context, port_id):
|
|
return self._get_neutron_resource(plugin_context, 'port', port_id)
|
|
|
|
def _update_port(self, plugin_context, port_id, attrs):
|
|
return self._update_neutron_resource(
|
|
plugin_context, 'port', port_id, attrs)
|
|
|
|
def _delete_port(self, plugin_context, port_id):
|
|
self._delete_neutron_resource(plugin_context, 'port', port_id)
|
|
|
|
def _create_subnet(self, plugin_context, attrs):
|
|
return self._create_neutron_resource(plugin_context, 'subnet', attrs)
|
|
|
|
def _get_subnet(self, plugin_context, subnet_id):
|
|
return self._get_neutron_resource(plugin_context, 'subnet', subnet_id)
|
|
|
|
def _get_subnets(self, plugin_context, filters={}):
|
|
return self._get_neutron_resources(plugin_context, 'subnet', filters)
|
|
|
|
def _update_subnet(self, plugin_context, subnet_id, attrs):
|
|
return self._update_neutron_resource(
|
|
plugin_context, 'subnet', subnet_id, attrs)
|
|
|
|
def _delete_subnet(self, plugin_context, subnet_id):
|
|
self._delete_neutron_resource(plugin_context, 'subnet', subnet_id)
|
|
|
|
def _create_network(self, plugin_context, attrs):
|
|
return self._create_neutron_resource(plugin_context, 'network', attrs)
|
|
|
|
def _get_network(self, plugin_context, network_id):
|
|
return self._get_neutron_resource(
|
|
plugin_context, 'network', network_id)
|
|
|
|
def _delete_network(self, plugin_context, network_id):
|
|
self._delete_neutron_resource(plugin_context, 'network', network_id)
|
|
|
|
def _create_router(self, plugin_context, attrs):
|
|
return self._create_neutron_resource(plugin_context, 'router', attrs)
|
|
|
|
def _get_router(self, plugin_context, router_id):
|
|
return self._get_neutron_resource(plugin_context, 'router', router_id)
|
|
|
|
def _update_router(self, plugin_context, router_id, attrs):
|
|
return self._update_neutron_resource(
|
|
plugin_context, 'router', router_id, attrs)
|
|
|
|
def _delete_router(self, plugin_context, router_id):
|
|
self._delete_neutron_resource(plugin_context, 'router', router_id)
|
|
|
|
def _add_router_interface(self, plugin_context, router_id, interface):
|
|
self._neutron.add_router_interface(
|
|
plugin_context, router_id, interface)
|
|
|
|
def _remove_router_interface(self, plugin_context, router_id, interface):
|
|
self._neutron.remove_router_interface(
|
|
plugin_context, router_id, interface)
|
|
|
|
def _add_router_gw_interface(self, plugin_context, router_id, gw_info):
|
|
return self._update_router(
|
|
plugin_context, router_id, {'external_gateway_info': gw_info})
|
|
|
|
def _remove_router_gw_interface(
|
|
self, plugin_context, router_id, interface_info):
|
|
self._update_router(
|
|
plugin_context, router_id, {'external_gateway_info': None})
|
|
|
|
def _create_sg(self, plugin_context, attrs):
|
|
return self._create_neutron_resource(
|
|
plugin_context, 'security_group', attrs)
|
|
|
|
def _get_sg(self, plugin_context, sg_id):
|
|
return self._get_neutron_resource(
|
|
plugin_context, 'security_group', sg_id)
|
|
|
|
def _get_sgs(self, plugin_context, filters={}):
|
|
return self._get_neutron_resources(
|
|
plugin_context, 'security_group', filters)
|
|
|
|
def _update_sg(self, plugin_context, sg_id, attrs):
|
|
return self._update_neutron_resource(
|
|
plugin_context, 'security_group', sg_id, attrs)
|
|
|
|
def _delete_sg(self, plugin_context, sg_id):
|
|
self._delete_neutron_resource(
|
|
plugin_context, 'security_group', sg_id)
|
|
|
|
def _create_sg_rule(self, plugin_context, attrs):
|
|
return self._create_neutron_resource(
|
|
plugin_context, 'security_group_rule', attrs)
|
|
|
|
def _get_sg_rule(self, plugin_context, sg_rule_id):
|
|
return self._get_neutron_resource(
|
|
plugin_context, 'security_group_rule', sg_rule_id)
|
|
|
|
def _get_sg_rules(self, plugin_context, filters={}):
|
|
return self._get_neutron_resources(
|
|
plugin_context, 'security_group_rule', filters)
|
|
|
|
# REVISIT(yi): update_security_group_rule not supported in neutron yet
|
|
# def _update_security_group_rule(self, plugin_context, sg_rule_id, attrs):
|
|
# return self._update_neutron_resource(
|
|
# plugin_context, 'security_group_rule', sg_rule_id, attrs)
|
|
|
|
def _delete_sg_rule(self, plugin_context, sg_rule_id):
|
|
self._delete_neutron_resource(
|
|
plugin_context, 'security_group_rule', sg_rule_id)
|
|
|
|
def _create_neutron_resource(self, context, resource, attrs):
|
|
action = 'create_' + resource
|
|
obj_creator = getattr(self._neutron, action)
|
|
obj = obj_creator(context, {resource: attrs})
|
|
return obj
|
|
|
|
def _get_neutron_resource(self, context, resource, resource_id):
|
|
obj_getter = getattr(self._neutron, 'show_' + resource)
|
|
obj = obj_getter(context, resource_id)
|
|
return obj
|
|
|
|
def _get_neutron_resources(self, context, resource, filters={}):
|
|
# REST APIs does not support ORing filtering
|
|
# Has to handle the combination of filters instead
|
|
filter_list = get_filter_combinations(filters)
|
|
resources = cm.get_resource_plural(resource)
|
|
obj_getter = getattr(self._neutron, 'list_' + resources)
|
|
res = []
|
|
for filter in filter_list:
|
|
obj = obj_getter(context, filter)
|
|
# merge the result and remove the duplicate
|
|
res.extend(x for x in obj if x not in res)
|
|
return res
|
|
|
|
def _update_neutron_resource(self, context, resource, resource_id, attrs):
|
|
action = 'update_' + resource
|
|
obj_updater = getattr(self._neutron, action)
|
|
obj = obj_updater(context, resource_id, {resource: attrs})
|
|
return obj
|
|
|
|
def _delete_neutron_resource(self, context, resource, resource_id):
|
|
action = 'delete_' + resource
|
|
obj_deleter = getattr(self._neutron, action)
|
|
obj_deleter(context, resource_id) |