From a7b1f969fe9651f16576c6a4b743a7a510779c2f Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Thu, 26 Jun 2014 16:14:17 +0900 Subject: [PATCH] remove unnecessary neutron files under neutron/extensions Change-Id: I775988fbb97070f3df4140acbaffa30b36196238 --- neutron/extensions/agent.py | 163 ------ neutron/extensions/allowedaddresspairs.py | 116 ----- neutron/extensions/dhcpagentscheduler.py | 152 ------ neutron/extensions/external_net.py | 68 --- neutron/extensions/extra_dhcp_opt.py | 91 ---- neutron/extensions/extraroute.py | 74 --- neutron/extensions/firewall.py | 431 ---------------- neutron/extensions/flavor.py | 67 --- neutron/extensions/l3.py | 254 ---------- neutron/extensions/l3_ext_gw_mode.py | 66 --- neutron/extensions/l3agentscheduler.py | 194 ------- neutron/extensions/lbaas_agentscheduler.py | 137 ----- neutron/extensions/loadbalancer.py | 506 ------------------- neutron/extensions/metering.py | 190 ------- neutron/extensions/multiprovidernet.py | 114 ----- neutron/extensions/portbindings.py | 133 ----- neutron/extensions/portsecurity.py | 78 --- neutron/extensions/providernet.py | 95 ---- neutron/extensions/quotasv2.py | 152 ------ neutron/extensions/routedserviceinsertion.py | 71 --- neutron/extensions/routerservicetype.py | 55 -- neutron/extensions/securitygroup.py | 354 ------------- neutron/extensions/servicetype.py | 91 ---- neutron/extensions/vpnaas.py | 482 ------------------ 24 files changed, 4134 deletions(-) delete mode 100644 neutron/extensions/agent.py delete mode 100644 neutron/extensions/allowedaddresspairs.py delete mode 100644 neutron/extensions/dhcpagentscheduler.py delete mode 100644 neutron/extensions/external_net.py delete mode 100644 neutron/extensions/extra_dhcp_opt.py delete mode 100644 neutron/extensions/extraroute.py delete mode 100644 neutron/extensions/firewall.py delete mode 100644 neutron/extensions/flavor.py delete mode 100644 neutron/extensions/l3.py delete mode 100644 neutron/extensions/l3_ext_gw_mode.py delete mode 100644 neutron/extensions/l3agentscheduler.py delete mode 100644 neutron/extensions/lbaas_agentscheduler.py delete mode 100644 neutron/extensions/loadbalancer.py delete mode 100644 neutron/extensions/metering.py delete mode 100644 neutron/extensions/multiprovidernet.py delete mode 100644 neutron/extensions/portbindings.py delete mode 100644 neutron/extensions/portsecurity.py delete mode 100644 neutron/extensions/providernet.py delete mode 100644 neutron/extensions/quotasv2.py delete mode 100644 neutron/extensions/routedserviceinsertion.py delete mode 100644 neutron/extensions/routerservicetype.py delete mode 100644 neutron/extensions/securitygroup.py delete mode 100644 neutron/extensions/servicetype.py delete mode 100644 neutron/extensions/vpnaas.py diff --git a/neutron/extensions/agent.py b/neutron/extensions/agent.py deleted file mode 100644 index 0dc0acd05..000000000 --- a/neutron/extensions/agent.py +++ /dev/null @@ -1,163 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation. -# -# 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 abc - -from neutron.api import extensions -from neutron.api.v2 import attributes as attr -from neutron.api.v2 import base -from neutron.common import exceptions -from neutron import manager - - -# Attribute Map -RESOURCE_NAME = 'agent' -RESOURCE_ATTRIBUTE_MAP = { - RESOURCE_NAME + 's': { - 'id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True}, - 'agent_type': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - 'binary': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - 'topic': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - 'host': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - 'admin_state_up': {'allow_post': False, 'allow_put': True, - 'convert_to': attr.convert_to_boolean, - 'is_visible': True}, - 'created_at': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - 'started_at': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - 'heartbeat_timestamp': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - 'alive': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - 'configurations': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - 'description': {'allow_post': False, 'allow_put': True, - 'is_visible': True, - 'validate': {'type:string': None}}, - }, -} - - -class AgentNotFound(exceptions.NotFound): - message = _("Agent %(id)s could not be found") - - -class AgentNotFoundByTypeHost(exceptions.NotFound): - message = _("Agent with agent_type=%(agent_type)s and host=%(host)s " - "could not be found") - - -class MultipleAgentFoundByTypeHost(exceptions.Conflict): - message = _("Multiple agents with agent_type=%(agent_type)s and " - "host=%(host)s found") - - -class Agent(object): - """Agent management extension.""" - - @classmethod - def get_name(cls): - return "agent" - - @classmethod - def get_alias(cls): - return "agent" - - @classmethod - def get_description(cls): - return "The agent management extension." - - @classmethod - def get_namespace(cls): - return "http://docs.openstack.org/ext/agent/api/v2.0" - - @classmethod - def get_updated(cls): - return "2013-02-03T10:00:00-00:00" - - @classmethod - def get_resources(cls): - """Returns Ext Resources.""" - my_plurals = [(key, key[:-1]) for key in RESOURCE_ATTRIBUTE_MAP.keys()] - attr.PLURALS.update(dict(my_plurals)) - plugin = manager.NeutronManager.get_plugin() - params = RESOURCE_ATTRIBUTE_MAP.get(RESOURCE_NAME + 's') - controller = base.create_resource(RESOURCE_NAME + 's', - RESOURCE_NAME, - plugin, params - ) - - ex = extensions.ResourceExtension(RESOURCE_NAME + 's', - controller) - - return [ex] - - def get_extended_resources(self, version): - if version == "2.0": - return RESOURCE_ATTRIBUTE_MAP - else: - return {} - - -class AgentPluginBase(object): - """REST API to operate the Agent. - - All of method must be in an admin context. - """ - - def create_agent(self, context, agent): - """Create agent. - - This operation is not allow in REST API. - @raise exceptions.BadRequest: - """ - raise exceptions.BadRequest - - @abc.abstractmethod - def delete_agent(self, context, id): - """Delete agent. - - Agents register themselves on reporting state. - But if a agent does not report its status - for a long time (for example, it is dead for ever. ), - admin can remove it. Agents must be disabled before - being removed. - """ - pass - - @abc.abstractmethod - def update_agent(self, context, agent): - """Disable or Enable the agent. - - Discription also can be updated. Some agents cannot be disabled, such - as plugins, services. An error code should be reported in this case. - @raise exceptions.BadRequest: - """ - pass - - @abc.abstractmethod - def get_agents(self, context, filters=None, fields=None): - pass - - @abc.abstractmethod - def get_agent(self, context, id, fields=None): - pass diff --git a/neutron/extensions/allowedaddresspairs.py b/neutron/extensions/allowedaddresspairs.py deleted file mode 100644 index a9328aaa4..000000000 --- a/neutron/extensions/allowedaddresspairs.py +++ /dev/null @@ -1,116 +0,0 @@ -# Copyright 2013 VMware, 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. - -import webob.exc - -from neutron.api.v2 import attributes as attr -from neutron.common import exceptions as nexception - - -class AllowedAddressPairsMissingIP(nexception.InvalidInput): - message = _("AllowedAddressPair must contain ip_address") - - -class AddressPairAndPortSecurityRequired(nexception.Conflict): - message = _("Port Security must be enabled in order to have allowed " - "address pairs on a port.") - - -class DuplicateAddressPairInRequest(nexception.InvalidInput): - message = _("Request contains duplicate address pair: " - "mac_address %(mac_address)s ip_address %(ip_address)s.") - - -def _validate_allowed_address_pairs(address_pairs, valid_values=None): - unique_check = {} - for address_pair in address_pairs: - # mac_address is optional, if not set we use the mac on the port - if 'mac_address' in address_pair: - msg = attr._validate_mac_address(address_pair['mac_address']) - if msg: - raise webob.exc.HTTPBadRequest(msg) - if 'ip_address' not in address_pair: - raise AllowedAddressPairsMissingIP() - - mac = address_pair.get('mac_address') - ip_address = address_pair['ip_address'] - if (mac, ip_address) not in unique_check: - unique_check[(mac, ip_address)] = None - else: - raise DuplicateAddressPairInRequest(mac_address=mac, - ip_address=ip_address) - - invalid_attrs = set(address_pair.keys()) - set(['mac_address', - 'ip_address']) - if invalid_attrs: - msg = (_("Unrecognized attribute(s) '%s'") % - ', '.join(set(address_pair.keys()) - - set(['mac_address', 'ip_address']))) - raise webob.exc.HTTPBadRequest(msg) - - if '/' in ip_address: - msg = attr._validate_subnet(ip_address) - else: - msg = attr._validate_ip_address(ip_address) - if msg: - raise webob.exc.HTTPBadRequest(msg) - -attr.validators['type:validate_allowed_address_pairs'] = ( - _validate_allowed_address_pairs) - -ADDRESS_PAIRS = 'allowed_address_pairs' -EXTENDED_ATTRIBUTES_2_0 = { - 'ports': { - ADDRESS_PAIRS: {'allow_post': True, 'allow_put': True, - 'convert_list_to': - attr.convert_kvp_list_to_dict, - 'validate': {'type:validate_allowed_address_pairs': - None}, - 'enforce_policy': True, - 'default': attr.ATTR_NOT_SPECIFIED, - 'is_visible': True}, - } -} - - -class Allowedaddresspairs(object): - """Extension class supporting allowed address pairs.""" - - @classmethod - def get_name(cls): - return "Allowed Address Pairs" - - @classmethod - def get_alias(cls): - return "allowed-address-pairs" - - @classmethod - def get_description(cls): - return "Provides allowed address pairs" - - @classmethod - def get_namespace(cls): - return "http://docs.openstack.org/ext/allowedaddresspairs/api/v2.0" - - @classmethod - def get_updated(cls): - return "2013-07-23T10:00:00-00:00" - - def get_extended_resources(self, version): - if version == "2.0": - attr.PLURALS.update({'allowed_address_pairs': - 'allowed_address_pair'}) - return EXTENDED_ATTRIBUTES_2_0 - else: - return {} diff --git a/neutron/extensions/dhcpagentscheduler.py b/neutron/extensions/dhcpagentscheduler.py deleted file mode 100644 index d86ba614f..000000000 --- a/neutron/extensions/dhcpagentscheduler.py +++ /dev/null @@ -1,152 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation. -# 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. - -import abc - -from neutron.api import extensions -from neutron.api.v2 import base -from neutron.api.v2 import resource -from neutron.common import constants -from neutron.common import exceptions -from neutron.extensions import agent -from neutron import manager -from neutron import policy -from neutron import wsgi - -DHCP_NET = 'dhcp-network' -DHCP_NETS = DHCP_NET + 's' -DHCP_AGENT = 'dhcp-agent' -DHCP_AGENTS = DHCP_AGENT + 's' - - -class NetworkSchedulerController(wsgi.Controller): - def index(self, request, **kwargs): - plugin = manager.NeutronManager.get_plugin() - policy.enforce(request.context, - "get_%s" % DHCP_NETS, - {}) - return plugin.list_networks_on_dhcp_agent( - request.context, kwargs['agent_id']) - - def create(self, request, body, **kwargs): - plugin = manager.NeutronManager.get_plugin() - policy.enforce(request.context, - "create_%s" % DHCP_NET, - {}) - return plugin.add_network_to_dhcp_agent( - request.context, kwargs['agent_id'], body['network_id']) - - def delete(self, request, id, **kwargs): - plugin = manager.NeutronManager.get_plugin() - policy.enforce(request.context, - "delete_%s" % DHCP_NET, - {}) - return plugin.remove_network_from_dhcp_agent( - request.context, kwargs['agent_id'], id) - - -class DhcpAgentsHostingNetworkController(wsgi.Controller): - def index(self, request, **kwargs): - plugin = manager.NeutronManager.get_plugin() - policy.enforce(request.context, - "get_%s" % DHCP_AGENTS, - {}) - return plugin.list_dhcp_agents_hosting_network( - request.context, kwargs['network_id']) - - -class Dhcpagentscheduler(extensions.ExtensionDescriptor): - """Extension class supporting dhcp agent scheduler. - """ - - @classmethod - def get_name(cls): - return "DHCP Agent Scheduler" - - @classmethod - def get_alias(cls): - return constants.DHCP_AGENT_SCHEDULER_EXT_ALIAS - - @classmethod - def get_description(cls): - return "Schedule networks among dhcp agents" - - @classmethod - def get_namespace(cls): - return "http://docs.openstack.org/ext/dhcp_agent_scheduler/api/v1.0" - - @classmethod - def get_updated(cls): - return "2013-02-07T10:00:00-00:00" - - @classmethod - def get_resources(cls): - """Returns Ext Resources.""" - exts = [] - parent = dict(member_name="agent", - collection_name="agents") - controller = resource.Resource(NetworkSchedulerController(), - base.FAULT_MAP) - exts.append(extensions.ResourceExtension( - DHCP_NETS, controller, parent)) - - parent = dict(member_name="network", - collection_name="networks") - - controller = resource.Resource(DhcpAgentsHostingNetworkController(), - base.FAULT_MAP) - exts.append(extensions.ResourceExtension( - DHCP_AGENTS, controller, parent)) - return exts - - def get_extended_resources(self, version): - return {} - - -class InvalidDHCPAgent(agent.AgentNotFound): - message = _("Agent %(id)s is not a valid DHCP Agent or has been disabled") - - -class NetworkHostedByDHCPAgent(exceptions.Conflict): - message = _("The network %(network_id)s has been already hosted" - " by the DHCP Agent %(agent_id)s.") - - -class NetworkNotHostedByDhcpAgent(exceptions.Conflict): - message = _("The network %(network_id)s is not hosted" - " by the DHCP agent %(agent_id)s.") - - -class DhcpAgentSchedulerPluginBase(object): - """REST API to operate the DHCP agent scheduler. - - All of method must be in an admin context. - """ - - @abc.abstractmethod - def add_network_to_dhcp_agent(self, context, id, network_id): - pass - - @abc.abstractmethod - def remove_network_from_dhcp_agent(self, context, id, network_id): - pass - - @abc.abstractmethod - def list_networks_on_dhcp_agent(self, context, id): - pass - - @abc.abstractmethod - def list_dhcp_agents_hosting_network(self, context, network_id): - pass diff --git a/neutron/extensions/external_net.py b/neutron/extensions/external_net.py deleted file mode 100644 index 6e50e93cb..000000000 --- a/neutron/extensions/external_net.py +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation. -# 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. - -from neutron.api import extensions -from neutron.api.v2 import attributes as attr -from neutron.common import exceptions as qexception -from neutron.extensions import l3 - - -class ExternalNetworkInUse(qexception.InUse): - message = _("External network %(net_id)s cannot be updated to be made " - "non-external, since it has existing gateway ports") - - -# For backward compatibility the 'router' prefix is kept. -EXTERNAL = 'router:external' -EXTENDED_ATTRIBUTES_2_0 = { - 'networks': {EXTERNAL: {'allow_post': True, - 'allow_put': True, - 'default': attr.ATTR_NOT_SPECIFIED, - 'is_visible': True, - 'convert_to': attr.convert_to_boolean, - 'enforce_policy': True, - 'required_by_policy': True}}} - - -class External_net(extensions.ExtensionDescriptor): - - @classmethod - def get_name(cls): - return "Neutron external network" - - @classmethod - def get_alias(cls): - return "external-net" - - @classmethod - def get_description(cls): - return _("Adds external network attribute to network resource.") - - @classmethod - def get_namespace(cls): - return "http://docs.openstack.org/ext/neutron/external_net/api/v1.0" - - @classmethod - def get_updated(cls): - return "2013-01-14T10:00:00-00:00" - - def get_extended_resources(self, version): - if version == "2.0": - return EXTENDED_ATTRIBUTES_2_0 - else: - return {} - - def get_alias_namespace_compatibility_map(self): - return {l3.L3.get_alias(): l3.L3.get_namespace()} diff --git a/neutron/extensions/extra_dhcp_opt.py b/neutron/extensions/extra_dhcp_opt.py deleted file mode 100644 index 59a3a0c59..000000000 --- a/neutron/extensions/extra_dhcp_opt.py +++ /dev/null @@ -1,91 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation. -# -# 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 Don Kehn, dekehn@gmail.com - -from neutron.api import extensions -from neutron.api.v2 import attributes as attr -from neutron.common import exceptions - - -# ExtraDHcpOpts Exceptions -class ExtraDhcpOptNotFound(exceptions.NotFound): - message = _("ExtraDhcpOpt %(id)s could not be found") - - -class ExtraDhcpOptBadData(exceptions.InvalidInput): - message = _("Invalid data format for extra-dhcp-opt: %(data)s") - - -def _validate_list_of_dict_or_none(data, key_specs=None): - if data is not None: - if not isinstance(data, list): - raise ExtraDhcpOptBadData(data=data) - for d in data: - msg = attr._validate_dict(d, key_specs) - if msg: - raise ExtraDhcpOptBadData(data=msg) - - -attr.validators['type:list_of_dict_or_none'] = _validate_list_of_dict_or_none - -# Attribute Map -EXTRADHCPOPTS = 'extra_dhcp_opts' - -EXTENDED_ATTRIBUTES_2_0 = { - 'ports': { - EXTRADHCPOPTS: - {'allow_post': True, - 'allow_put': True, - 'is_visible': True, - 'default': None, - 'validate': { - 'type:list_of_dict_or_none': { - 'id': {'type:uuid': None, 'required': False}, - 'opt_name': {'type:not_empty_string': None, - 'required': True}, - 'opt_value': {'type:not_empty_string_or_none': None, - 'required': True}}}}}} - - -class Extra_dhcp_opt(extensions.ExtensionDescriptor): - @classmethod - def get_name(cls): - return "Neutron Extra DHCP opts" - - @classmethod - def get_alias(cls): - return "extra_dhcp_opt" - - @classmethod - def get_description(cls): - return ("Extra options configuration for DHCP. " - "For example PXE boot options to DHCP clients can " - "be specified (e.g. tftp-server, server-ip-address, " - "bootfile-name)") - - @classmethod - def get_namespace(cls): - return "http://docs.openstack.org/ext/neutron/extra_dhcp_opt/api/v1.0" - - @classmethod - def get_updated(cls): - return "2013-03-17T12:00:00-00:00" - - def get_extended_resources(self, version): - if version == "2.0": - return EXTENDED_ATTRIBUTES_2_0 - else: - return {} diff --git a/neutron/extensions/extraroute.py b/neutron/extensions/extraroute.py deleted file mode 100644 index 7c63baa22..000000000 --- a/neutron/extensions/extraroute.py +++ /dev/null @@ -1,74 +0,0 @@ -# Copyright 2013, Nachi Ueno, NTT MCL, 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. - - -from neutron.api.v2 import attributes as attr -from neutron.common import exceptions as qexception - - -# Extra Routes Exceptions -class InvalidRoutes(qexception.InvalidInput): - message = _("Invalid format for routes: %(routes)s, %(reason)s") - - -class RouterInterfaceInUseByRoute(qexception.InUse): - message = _("Router interface for subnet %(subnet_id)s on router " - "%(router_id)s cannot be deleted, as it is required " - "by one or more routes.") - - -class RoutesExhausted(qexception.BadRequest): - message = _("Unable to complete operation for %(router_id)s. " - "The number of routes exceeds the maximum %(quota)s.") - -# Attribute Map -EXTENDED_ATTRIBUTES_2_0 = { - 'routers': { - 'routes': {'allow_post': False, 'allow_put': True, - 'validate': {'type:hostroutes': None}, - 'convert_to': attr.convert_none_to_empty_list, - 'is_visible': True, 'default': attr.ATTR_NOT_SPECIFIED}, - } -} - - -class Extraroute(): - - @classmethod - def get_name(cls): - return "Neutron Extra Route" - - @classmethod - def get_alias(cls): - return "extraroute" - - @classmethod - def get_description(cls): - return "Extra routes configuration for L3 router" - - @classmethod - def get_namespace(cls): - return "http://docs.openstack.org/ext/neutron/extraroutes/api/v1.0" - - @classmethod - def get_updated(cls): - return "2013-02-01T10:00:00-00:00" - - def get_extended_resources(self, version): - if version == "2.0": - attr.PLURALS.update({'routes': 'route'}) - return EXTENDED_ATTRIBUTES_2_0 - else: - return {} diff --git a/neutron/extensions/firewall.py b/neutron/extensions/firewall.py deleted file mode 100644 index bbb5d163e..000000000 --- a/neutron/extensions/firewall.py +++ /dev/null @@ -1,431 +0,0 @@ -# Copyright 2013 Big Switch Networks, 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: Sumit Naiksatam, sumitnaiksatam@gmail.com, Big Switch Networks, Inc. - -import abc - -from oslo.config import cfg -import six - -from neutron.api import extensions -from neutron.api.v2 import attributes as attr -from neutron.api.v2 import resource_helper -from neutron.common import exceptions as qexception -from neutron.openstack.common import log as logging -from neutron.plugins.common import constants -from neutron.services import service_base - - -LOG = logging.getLogger(__name__) - - -# Firewall Exceptions -class FirewallNotFound(qexception.NotFound): - message = _("Firewall %(firewall_id)s could not be found.") - - -class FirewallInUse(qexception.InUse): - message = _("Firewall %(firewall_id)s is still active.") - - -class FirewallInPendingState(qexception.Conflict): - message = _("Operation cannot be performed since associated Firewall " - "%(firewall_id)s is in %(pending_state)s.") - - -class FirewallPolicyNotFound(qexception.NotFound): - message = _("Firewall Policy %(firewall_policy_id)s could not be found.") - - -class FirewallPolicyInUse(qexception.InUse): - message = _("Firewall Policy %(firewall_policy_id)s is being used.") - - -class FirewallRuleNotFound(qexception.NotFound): - message = _("Firewall Rule %(firewall_rule_id)s could not be found.") - - -class FirewallRuleInUse(qexception.InUse): - message = _("Firewall Rule %(firewall_rule_id)s is being used.") - - -class FirewallRuleNotAssociatedWithPolicy(qexception.InvalidInput): - message = _("Firewall Rule %(firewall_rule_id)s is not associated " - " with Firewall Policy %(firewall_policy_id)s.") - - -class FirewallRuleInvalidProtocol(qexception.InvalidInput): - message = _("Firewall Rule protocol %(protocol)s is not supported. " - "Only protocol values %(values)s and their integer " - "representation (0 to 255) are supported.") - - -class FirewallRuleInvalidAction(qexception.InvalidInput): - message = _("Firewall rule action %(action)s is not supported. " - "Only action values %(values)s are supported.") - - -class FirewallRuleInvalidICMPParameter(qexception.InvalidInput): - message = _("%(param)s are not allowed when protocol " - "is set to ICMP.") - - -class FirewallInvalidPortValue(qexception.InvalidInput): - message = _("Invalid value for port %(port)s.") - - -class FirewallRuleInfoMissing(qexception.InvalidInput): - message = _("Missing rule info argument for insert/remove " - "rule operation.") - - -class FirewallInternalDriverError(qexception.NeutronException): - """Fwaas exception for all driver errors. - - On any failure or exception in the driver, driver should log it and - raise this exception to the agent - """ - message = _("%(driver)s: Internal driver error.") - - -fw_valid_protocol_values = [None, constants.TCP, constants.UDP, constants.ICMP] -fw_valid_action_values = [constants.FWAAS_ALLOW, constants.FWAAS_DENY] - - -def convert_protocol(value): - if value is None: - return - if value.isdigit(): - val = int(value) - if 0 <= val <= 255: - return val - else: - raise FirewallRuleInvalidProtocol(protocol=value, - values= - fw_valid_protocol_values) - elif value.lower() in fw_valid_protocol_values: - return value.lower() - else: - raise FirewallRuleInvalidProtocol(protocol=value, - values= - fw_valid_protocol_values) - - -def convert_action_to_case_insensitive(value): - if value is None: - return - else: - return value.lower() - - -def convert_port_to_string(value): - if value is None: - return - else: - return str(value) - - -def _validate_port_range(data, key_specs=None): - if data is None: - return - data = str(data) - ports = data.split(':') - for p in ports: - try: - val = int(p) - except (ValueError, TypeError): - msg = _("Port '%s' is not a valid number") % p - LOG.debug(msg) - return msg - if val <= 0 or val > 65535: - msg = _("Invalid port '%s'") % p - LOG.debug(msg) - return msg - - -def _validate_ip_or_subnet_or_none(data, valid_values=None): - if data is None: - return None - msg_ip = attr._validate_ip_address(data, valid_values) - if not msg_ip: - return - msg_subnet = attr._validate_subnet(data, valid_values) - if not msg_subnet: - return - return _("%(msg_ip)s and %(msg_subnet)s") % {'msg_ip': msg_ip, - 'msg_subnet': msg_subnet} - - -attr.validators['type:port_range'] = _validate_port_range -attr.validators['type:ip_or_subnet_or_none'] = _validate_ip_or_subnet_or_none - - -RESOURCE_ATTRIBUTE_MAP = { - 'firewall_rules': { - 'id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True, 'primary_key': True}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'required_by_policy': True, - 'is_visible': True}, - 'name': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'description': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'firewall_policy_id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:uuid_or_none': None}, - 'is_visible': True}, - 'shared': {'allow_post': True, 'allow_put': True, - 'default': False, 'convert_to': attr.convert_to_boolean, - 'is_visible': True, 'required_by_policy': True, - 'enforce_policy': True}, - 'protocol': {'allow_post': True, 'allow_put': True, - 'is_visible': True, 'default': None, - 'convert_to': convert_protocol, - 'validate': {'type:values': fw_valid_protocol_values}}, - 'ip_version': {'allow_post': True, 'allow_put': True, - 'default': 4, 'convert_to': attr.convert_to_int, - 'validate': {'type:values': [4, 6]}, - 'is_visible': True}, - 'source_ip_address': {'allow_post': True, 'allow_put': True, - 'validate': {'type:ip_or_subnet_or_none': None}, - 'is_visible': True, 'default': None}, - 'destination_ip_address': {'allow_post': True, 'allow_put': True, - 'validate': {'type:ip_or_subnet_or_none': - None}, - 'is_visible': True, 'default': None}, - 'source_port': {'allow_post': True, 'allow_put': True, - 'validate': {'type:port_range': None}, - 'convert_to': convert_port_to_string, - 'default': None, 'is_visible': True}, - 'destination_port': {'allow_post': True, 'allow_put': True, - 'validate': {'type:port_range': None}, - 'convert_to': convert_port_to_string, - 'default': None, 'is_visible': True}, - 'position': {'allow_post': False, 'allow_put': False, - 'default': None, 'is_visible': True}, - 'action': {'allow_post': True, 'allow_put': True, - 'convert_to': convert_action_to_case_insensitive, - 'validate': {'type:values': fw_valid_action_values}, - 'is_visible': True, 'default': 'deny'}, - 'enabled': {'allow_post': True, 'allow_put': True, - 'default': True, 'convert_to': attr.convert_to_boolean, - 'is_visible': True}, - }, - 'firewall_policies': { - 'id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True, - 'primary_key': True}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'required_by_policy': True, - 'is_visible': True}, - 'name': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'description': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'shared': {'allow_post': True, 'allow_put': True, - 'default': False, 'convert_to': attr.convert_to_boolean, - 'is_visible': True, 'required_by_policy': True, - 'enforce_policy': True}, - 'firewall_rules': {'allow_post': True, 'allow_put': True, - 'validate': {'type:uuid_list': None}, - 'convert_to': attr.convert_none_to_empty_list, - 'default': None, 'is_visible': True}, - 'audited': {'allow_post': True, 'allow_put': True, - 'default': False, 'convert_to': attr.convert_to_boolean, - 'is_visible': True}, - }, - 'firewalls': { - 'id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True, - 'primary_key': True}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'required_by_policy': True, - 'is_visible': True}, - 'name': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'description': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'admin_state_up': {'allow_post': True, 'allow_put': True, - 'default': True, - 'convert_to': attr.convert_to_boolean, - 'is_visible': True}, - 'status': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - 'shared': {'allow_post': True, 'allow_put': True, - 'default': False, 'convert_to': attr.convert_to_boolean, - 'is_visible': False, 'required_by_policy': True, - 'enforce_policy': True}, - 'firewall_policy_id': {'allow_post': True, 'allow_put': True, - 'validate': {'type:uuid_or_none': None}, - 'is_visible': True}, - }, -} - -firewall_quota_opts = [ - cfg.IntOpt('quota_firewall', - default=1, - help=_('Number of firewalls allowed per tenant. ' - 'A negative value means unlimited.')), - cfg.IntOpt('quota_firewall_policy', - default=1, - help=_('Number of firewall policies allowed per tenant. ' - 'A negative value means unlimited.')), - cfg.IntOpt('quota_firewall_rule', - default=-1, - help=_('Number of firewall rules allowed per tenant. ' - 'A negative value means unlimited.')), -] -cfg.CONF.register_opts(firewall_quota_opts, 'QUOTAS') - - -class Firewall(extensions.ExtensionDescriptor): - - @classmethod - def get_name(cls): - return "Firewall service" - - @classmethod - def get_alias(cls): - return "fwaas" - - @classmethod - def get_description(cls): - return "Extension for Firewall service" - - @classmethod - def get_namespace(cls): - return "http://wiki.openstack.org/Neutron/FWaaS/API_1.0" - - @classmethod - def get_updated(cls): - return "2013-02-25T10:00:00-00:00" - - @classmethod - def get_resources(cls): - special_mappings = {'firewall_policies': 'firewall_policy'} - plural_mappings = resource_helper.build_plural_mappings( - special_mappings, RESOURCE_ATTRIBUTE_MAP) - attr.PLURALS.update(plural_mappings) - action_map = {'firewall_policy': {'insert_rule': 'PUT', - 'remove_rule': 'PUT'}} - return resource_helper.build_resource_info(plural_mappings, - RESOURCE_ATTRIBUTE_MAP, - constants.FIREWALL, - action_map=action_map) - - @classmethod - def get_plugin_interface(cls): - return FirewallPluginBase - - def update_attributes_map(self, attributes): - super(Firewall, self).update_attributes_map( - attributes, extension_attrs_map=RESOURCE_ATTRIBUTE_MAP) - - def get_extended_resources(self, version): - if version == "2.0": - return RESOURCE_ATTRIBUTE_MAP - else: - return {} - - -@six.add_metaclass(abc.ABCMeta) -class FirewallPluginBase(service_base.ServicePluginBase): - - def get_plugin_name(self): - return constants.FIREWALL - - def get_plugin_type(self): - return constants.FIREWALL - - def get_plugin_description(self): - return 'Firewall service plugin' - - @abc.abstractmethod - def get_firewalls(self, context, filters=None, fields=None): - pass - - @abc.abstractmethod - def get_firewall(self, context, id, fields=None): - pass - - @abc.abstractmethod - def create_firewall(self, context, firewall): - pass - - @abc.abstractmethod - def update_firewall(self, context, id, firewall): - pass - - @abc.abstractmethod - def delete_firewall(self, context, id): - pass - - @abc.abstractmethod - def get_firewall_rules(self, context, filters=None, fields=None): - pass - - @abc.abstractmethod - def get_firewall_rule(self, context, id, fields=None): - pass - - @abc.abstractmethod - def create_firewall_rule(self, context, firewall_rule): - pass - - @abc.abstractmethod - def update_firewall_rule(self, context, id, firewall_rule): - pass - - @abc.abstractmethod - def delete_firewall_rule(self, context, id): - pass - - @abc.abstractmethod - def get_firewall_policy(self, context, id, fields=None): - pass - - @abc.abstractmethod - def get_firewall_policies(self, context, filters=None, fields=None): - pass - - @abc.abstractmethod - def create_firewall_policy(self, context, firewall_policy): - pass - - @abc.abstractmethod - def update_firewall_policy(self, context, id, firewall_policy): - pass - - @abc.abstractmethod - def delete_firewall_policy(self, context, id): - pass - - @abc.abstractmethod - def insert_rule(self, context, id, rule_info): - pass - - @abc.abstractmethod - def remove_rule(self, context, id, rule_info): - pass diff --git a/neutron/extensions/flavor.py b/neutron/extensions/flavor.py deleted file mode 100644 index c5937d932..000000000 --- a/neutron/extensions/flavor.py +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright 2012 Nachi Ueno, NTT MCL, 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. - -from neutron.api import extensions -from neutron.api.v2 import attributes -from neutron.openstack.common import log as logging - - -LOG = logging.getLogger(__name__) - -FLAVOR_NETWORK = 'flavor:network' -FLAVOR_ROUTER = 'flavor:router' - -FLAVOR_ATTRIBUTE = { - 'networks': { - FLAVOR_NETWORK: {'allow_post': True, - 'allow_put': False, - 'is_visible': True, - 'default': attributes.ATTR_NOT_SPECIFIED} - }, - 'routers': { - FLAVOR_ROUTER: {'allow_post': True, - 'allow_put': False, - 'is_visible': True, - 'default': attributes.ATTR_NOT_SPECIFIED} - } -} - - -class Flavor(extensions.ExtensionDescriptor): - @classmethod - def get_name(cls): - return "Flavor support for network and router" - - @classmethod - def get_alias(cls): - return "flavor" - - @classmethod - def get_description(cls): - return "Flavor" - - @classmethod - def get_namespace(cls): - return "http://docs.openstack.org/ext/flavor/api/v1.0" - - @classmethod - def get_updated(cls): - return "2012-07-20T10:00:00-00:00" - - def get_extended_resources(self, version): - if version == "2.0": - return FLAVOR_ATTRIBUTE - else: - return {} diff --git a/neutron/extensions/l3.py b/neutron/extensions/l3.py deleted file mode 100644 index b02c9337b..000000000 --- a/neutron/extensions/l3.py +++ /dev/null @@ -1,254 +0,0 @@ -# Copyright 2012 VMware, 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. - -import abc - -from oslo.config import cfg - -from neutron.api import extensions -from neutron.api.v2 import attributes as attr -from neutron.api.v2 import resource_helper -from neutron.common import exceptions as qexception -from neutron.plugins.common import constants - - -# L3 Exceptions -class RouterNotFound(qexception.NotFound): - message = _("Router %(router_id)s could not be found") - - -class RouterInUse(qexception.InUse): - message = _("Router %(router_id)s still has ports") - - -class RouterInterfaceNotFound(qexception.NotFound): - message = _("Router %(router_id)s does not have " - "an interface with id %(port_id)s") - - -class RouterInterfaceNotFoundForSubnet(qexception.NotFound): - message = _("Router %(router_id)s has no interface " - "on subnet %(subnet_id)s") - - -class RouterInterfaceInUseByFloatingIP(qexception.InUse): - message = _("Router interface for subnet %(subnet_id)s on router " - "%(router_id)s cannot be deleted, as it is required " - "by one or more floating IPs.") - - -class FloatingIPNotFound(qexception.NotFound): - message = _("Floating IP %(floatingip_id)s could not be found") - - -class ExternalGatewayForFloatingIPNotFound(qexception.NotFound): - message = _("External network %(external_network_id)s is not reachable " - "from subnet %(subnet_id)s. Therefore, cannot associate " - "Port %(port_id)s with a Floating IP.") - - -class FloatingIPPortAlreadyAssociated(qexception.InUse): - message = _("Cannot associate floating IP %(floating_ip_address)s " - "(%(fip_id)s) with port %(port_id)s " - "using fixed IP %(fixed_ip)s, as that fixed IP already " - "has a floating IP on external network %(net_id)s.") - - -class L3PortInUse(qexception.InUse): - message = _("Port %(port_id)s has owner %(device_owner)s and therefore" - " cannot be deleted directly via the port API.") - - -class RouterExternalGatewayInUseByFloatingIp(qexception.InUse): - message = _("Gateway cannot be updated for router %(router_id)s, since a " - "gateway to external network %(net_id)s is required by one or " - "more floating IPs.") - -ROUTERS = 'routers' -EXTERNAL_GW_INFO = 'external_gateway_info' - -RESOURCE_ATTRIBUTE_MAP = { - ROUTERS: { - 'id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True, - 'primary_key': True}, - 'name': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'admin_state_up': {'allow_post': True, 'allow_put': True, - 'default': True, - 'convert_to': attr.convert_to_boolean, - 'is_visible': True}, - 'status': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'required_by_policy': True, - 'validate': {'type:string': None}, - 'is_visible': True}, - EXTERNAL_GW_INFO: {'allow_post': True, 'allow_put': True, - 'is_visible': True, 'default': None, - 'enforce_policy': True} - }, - 'floatingips': { - 'id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True, - 'primary_key': True}, - 'floating_ip_address': {'allow_post': False, 'allow_put': False, - 'validate': {'type:ip_address_or_none': None}, - 'is_visible': True}, - 'floating_network_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True}, - 'router_id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:uuid_or_none': None}, - 'is_visible': True, 'default': None}, - 'port_id': {'allow_post': True, 'allow_put': True, - 'validate': {'type:uuid_or_none': None}, - 'is_visible': True, 'default': None, - 'required_by_policy': True}, - 'fixed_ip_address': {'allow_post': True, 'allow_put': True, - 'validate': {'type:ip_address_or_none': None}, - 'is_visible': True, 'default': None}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'required_by_policy': True, - 'validate': {'type:string': None}, - 'is_visible': True}, - 'status': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - }, -} - -l3_quota_opts = [ - cfg.IntOpt('quota_router', - default=10, - help=_('Number of routers allowed per tenant. ' - 'A negative value means unlimited.')), - cfg.IntOpt('quota_floatingip', - default=50, - help=_('Number of floating IPs allowed per tenant. ' - 'A negative value means unlimited.')), -] -cfg.CONF.register_opts(l3_quota_opts, 'QUOTAS') - - -class L3(extensions.ExtensionDescriptor): - - @classmethod - def get_name(cls): - return "Neutron L3 Router" - - @classmethod - def get_alias(cls): - return "router" - - @classmethod - def get_description(cls): - return ("Router abstraction for basic L3 forwarding" - " between L2 Neutron networks and access to external" - " networks via a NAT gateway.") - - @classmethod - def get_namespace(cls): - return "http://docs.openstack.org/ext/neutron/router/api/v1.0" - - @classmethod - def get_updated(cls): - return "2012-07-20T10:00:00-00:00" - - @classmethod - def get_resources(cls): - """Returns Ext Resources.""" - plural_mappings = resource_helper.build_plural_mappings( - {}, RESOURCE_ATTRIBUTE_MAP) - attr.PLURALS.update(plural_mappings) - action_map = {'router': {'add_router_interface': 'PUT', - 'remove_router_interface': 'PUT'}} - return resource_helper.build_resource_info(plural_mappings, - RESOURCE_ATTRIBUTE_MAP, - constants.L3_ROUTER_NAT, - action_map=action_map, - register_quota=True) - - def update_attributes_map(self, attributes): - super(L3, self).update_attributes_map( - attributes, extension_attrs_map=RESOURCE_ATTRIBUTE_MAP) - - def get_extended_resources(self, version): - if version == "2.0": - return RESOURCE_ATTRIBUTE_MAP - else: - return {} - - -class RouterPluginBase(object): - - @abc.abstractmethod - def create_router(self, context, router): - pass - - @abc.abstractmethod - def update_router(self, context, id, router): - pass - - @abc.abstractmethod - def get_router(self, context, id, fields=None): - pass - - @abc.abstractmethod - def delete_router(self, context, id): - pass - - @abc.abstractmethod - def get_routers(self, context, filters=None, fields=None, - sorts=None, limit=None, marker=None, page_reverse=False): - pass - - @abc.abstractmethod - def add_router_interface(self, context, router_id, interface_info): - pass - - @abc.abstractmethod - def remove_router_interface(self, context, router_id, interface_info): - pass - - @abc.abstractmethod - def create_floatingip(self, context, floatingip): - pass - - @abc.abstractmethod - def update_floatingip(self, context, id, floatingip): - pass - - @abc.abstractmethod - def get_floatingip(self, context, id, fields=None): - pass - - @abc.abstractmethod - def delete_floatingip(self, context, id): - pass - - @abc.abstractmethod - def get_floatingips(self, context, filters=None, fields=None, - sorts=None, limit=None, marker=None, - page_reverse=False): - pass - - def get_routers_count(self, context, filters=None): - raise NotImplementedError() - - def get_floatingips_count(self, context, filters=None): - raise NotImplementedError() diff --git a/neutron/extensions/l3_ext_gw_mode.py b/neutron/extensions/l3_ext_gw_mode.py deleted file mode 100644 index 31c943a9c..000000000 --- a/neutron/extensions/l3_ext_gw_mode.py +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright 2013 VMware, 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. - -from neutron.api import extensions -from neutron.api.v2 import attributes as attrs -from neutron.extensions import l3 - - -EXTENDED_ATTRIBUTES_2_0 = { - 'routers': {l3.EXTERNAL_GW_INFO: - {'allow_post': True, - 'allow_put': True, - 'is_visible': True, - 'default': None, - 'enforce_policy': True, - 'validate': - {'type:dict_or_nodata': - {'network_id': {'type:uuid': None, 'required': True}, - 'enable_snat': {'type:boolean': None, 'required': False, - 'convert_to': attrs.convert_to_boolean}} - }}}} - - -class L3_ext_gw_mode(extensions.ExtensionDescriptor): - - @classmethod - def get_name(cls): - return "Neutron L3 Configurable external gateway mode" - - @classmethod - def get_alias(cls): - return "ext-gw-mode" - - @classmethod - def get_description(cls): - return ("Extension of the router abstraction for specifying whether " - "SNAT should occur on the external gateway") - - @classmethod - def get_namespace(cls): - return "http://docs.openstack.org/ext/neutron/ext-gw-mode/api/v1.0" - - @classmethod - def get_updated(cls): - return "2013-03-28T10:00:00-00:00" - - def get_required_extensions(self): - return ["router"] - - def get_extended_resources(self, version): - if version == "2.0": - return dict(EXTENDED_ATTRIBUTES_2_0.items()) - else: - return {} diff --git a/neutron/extensions/l3agentscheduler.py b/neutron/extensions/l3agentscheduler.py deleted file mode 100644 index 689cc9ba9..000000000 --- a/neutron/extensions/l3agentscheduler.py +++ /dev/null @@ -1,194 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation. -# 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. - -import abc - -import webob.exc - -from neutron.api import extensions -from neutron.api.v2 import base -from neutron.api.v2 import resource -from neutron.common import constants -from neutron.common import exceptions -from neutron.extensions import agent -from neutron import manager -from neutron.openstack.common import log as logging -from neutron.plugins.common import constants as service_constants -from neutron import policy -from neutron import wsgi - - -LOG = logging.getLogger(__name__) - - -L3_ROUTER = 'l3-router' -L3_ROUTERS = L3_ROUTER + 's' -L3_AGENT = 'l3-agent' -L3_AGENTS = L3_AGENT + 's' - - -class RouterSchedulerController(wsgi.Controller): - def get_plugin(self): - plugin = manager.NeutronManager.get_service_plugins().get( - service_constants.L3_ROUTER_NAT) - if not plugin: - LOG.error(_('No plugin for L3 routing registered to handle ' - 'router scheduling')) - msg = _('The resource could not be found.') - raise webob.exc.HTTPNotFound(msg) - return plugin - - def index(self, request, **kwargs): - plugin = self.get_plugin() - policy.enforce(request.context, - "get_%s" % L3_ROUTERS, - {}) - return plugin.list_routers_on_l3_agent( - request.context, kwargs['agent_id']) - - def create(self, request, body, **kwargs): - plugin = self.get_plugin() - policy.enforce(request.context, - "create_%s" % L3_ROUTER, - {}) - return plugin.add_router_to_l3_agent( - request.context, - kwargs['agent_id'], - body['router_id']) - - def delete(self, request, id, **kwargs): - plugin = self.get_plugin() - policy.enforce(request.context, - "delete_%s" % L3_ROUTER, - {}) - return plugin.remove_router_from_l3_agent( - request.context, kwargs['agent_id'], id) - - -class L3AgentsHostingRouterController(wsgi.Controller): - def get_plugin(self): - plugin = manager.NeutronManager.get_service_plugins().get( - service_constants.L3_ROUTER_NAT) - if not plugin: - LOG.error(_('No plugin for L3 routing registered to handle ' - 'router scheduling')) - msg = _('The resource could not be found.') - raise webob.exc.HTTPNotFound(msg) - return plugin - - def index(self, request, **kwargs): - plugin = manager.NeutronManager.get_service_plugins().get( - service_constants.L3_ROUTER_NAT) - policy.enforce(request.context, - "get_%s" % L3_AGENTS, - {}) - return plugin.list_l3_agents_hosting_router( - request.context, kwargs['router_id']) - - -class L3agentscheduler(extensions.ExtensionDescriptor): - """Extension class supporting l3 agent scheduler. - """ - - @classmethod - def get_name(cls): - return "L3 Agent Scheduler" - - @classmethod - def get_alias(cls): - return constants.L3_AGENT_SCHEDULER_EXT_ALIAS - - @classmethod - def get_description(cls): - return "Schedule routers among l3 agents" - - @classmethod - def get_namespace(cls): - return "http://docs.openstack.org/ext/l3_agent_scheduler/api/v1.0" - - @classmethod - def get_updated(cls): - return "2013-02-07T10:00:00-00:00" - - @classmethod - def get_resources(cls): - """Returns Ext Resources.""" - exts = [] - parent = dict(member_name="agent", - collection_name="agents") - - controller = resource.Resource(RouterSchedulerController(), - base.FAULT_MAP) - exts.append(extensions.ResourceExtension( - L3_ROUTERS, controller, parent)) - - parent = dict(member_name="router", - collection_name="routers") - - controller = resource.Resource(L3AgentsHostingRouterController(), - base.FAULT_MAP) - exts.append(extensions.ResourceExtension( - L3_AGENTS, controller, parent)) - return exts - - def get_extended_resources(self, version): - return {} - - -class InvalidL3Agent(agent.AgentNotFound): - message = _("Agent %(id)s is not a L3 Agent or has been disabled") - - -class RouterHostedByL3Agent(exceptions.Conflict): - message = _("The router %(router_id)s has been already hosted" - " by the L3 Agent %(agent_id)s.") - - -class RouterSchedulingFailed(exceptions.Conflict): - message = _("Failed scheduling router %(router_id)s to" - " the L3 Agent %(agent_id)s.") - - -class RouterReschedulingFailed(exceptions.Conflict): - message = _("Failed rescheduling router %(router_id)s: " - "no eligible l3 agent found.") - - -class RouterNotHostedByL3Agent(exceptions.Conflict): - message = _("The router %(router_id)s is not hosted" - " by L3 agent %(agent_id)s.") - - -class L3AgentSchedulerPluginBase(object): - """REST API to operate the l3 agent scheduler. - - All of method must be in an admin context. - """ - - @abc.abstractmethod - def add_router_to_l3_agent(self, context, id, router_id): - pass - - @abc.abstractmethod - def remove_router_from_l3_agent(self, context, id, router_id): - pass - - @abc.abstractmethod - def list_routers_on_l3_agent(self, context, id): - pass - - @abc.abstractmethod - def list_l3_agents_hosting_router(self, context, router_id): - pass diff --git a/neutron/extensions/lbaas_agentscheduler.py b/neutron/extensions/lbaas_agentscheduler.py deleted file mode 100644 index a821cb6e8..000000000 --- a/neutron/extensions/lbaas_agentscheduler.py +++ /dev/null @@ -1,137 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation. -# 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. - -import abc - -from neutron.api import extensions -from neutron.api.v2 import base -from neutron.api.v2 import resource -from neutron.common import constants -from neutron.extensions import agent -from neutron.extensions import loadbalancer -from neutron import manager -from neutron.plugins.common import constants as plugin_const -from neutron import policy -from neutron import wsgi - -LOADBALANCER_POOL = 'loadbalancer-pool' -LOADBALANCER_POOLS = LOADBALANCER_POOL + 's' -LOADBALANCER_AGENT = 'loadbalancer-agent' - - -class PoolSchedulerController(wsgi.Controller): - def index(self, request, **kwargs): - lbaas_plugin = manager.NeutronManager.get_service_plugins().get( - plugin_const.LOADBALANCER) - if not lbaas_plugin: - return {'pools': []} - - policy.enforce(request.context, - "get_%s" % LOADBALANCER_POOLS, - {}, - plugin=lbaas_plugin) - return lbaas_plugin.list_pools_on_lbaas_agent( - request.context, kwargs['agent_id']) - - -class LbaasAgentHostingPoolController(wsgi.Controller): - def index(self, request, **kwargs): - lbaas_plugin = manager.NeutronManager.get_service_plugins().get( - plugin_const.LOADBALANCER) - if not lbaas_plugin: - return - - policy.enforce(request.context, - "get_%s" % LOADBALANCER_AGENT, - {}, - plugin=lbaas_plugin) - return lbaas_plugin.get_lbaas_agent_hosting_pool( - request.context, kwargs['pool_id']) - - -class Lbaas_agentscheduler(extensions.ExtensionDescriptor): - """Extension class supporting LBaaS agent scheduler. - """ - - @classmethod - def get_name(cls): - return "Loadbalancer Agent Scheduler" - - @classmethod - def get_alias(cls): - return constants.LBAAS_AGENT_SCHEDULER_EXT_ALIAS - - @classmethod - def get_description(cls): - return "Schedule pools among lbaas agents" - - @classmethod - def get_namespace(cls): - return "http://docs.openstack.org/ext/lbaas_agent_scheduler/api/v1.0" - - @classmethod - def get_updated(cls): - return "2013-02-07T10:00:00-00:00" - - @classmethod - def get_resources(cls): - """Returns Ext Resources.""" - exts = [] - parent = dict(member_name="agent", - collection_name="agents") - - controller = resource.Resource(PoolSchedulerController(), - base.FAULT_MAP) - exts.append(extensions.ResourceExtension( - LOADBALANCER_POOLS, controller, parent)) - - parent = dict(member_name="pool", - collection_name="pools") - - controller = resource.Resource(LbaasAgentHostingPoolController(), - base.FAULT_MAP) - exts.append(extensions.ResourceExtension( - LOADBALANCER_AGENT, controller, parent, - path_prefix=plugin_const. - COMMON_PREFIXES[plugin_const.LOADBALANCER])) - return exts - - def get_extended_resources(self, version): - return {} - - -class NoEligibleLbaasAgent(loadbalancer.NoEligibleBackend): - message = _("No eligible loadbalancer agent found " - "for pool %(pool_id)s.") - - -class NoActiveLbaasAgent(agent.AgentNotFound): - message = _("No active loadbalancer agent found " - "for pool %(pool_id)s.") - - -class LbaasAgentSchedulerPluginBase(object): - """REST API to operate the lbaas agent scheduler. - - All of method must be in an admin context. - """ - - @abc.abstractmethod - def list_pools_on_lbaas_agent(self, context, id): - pass - - @abc.abstractmethod - def get_lbaas_agent_hosting_pool(self, context, pool_id): - pass diff --git a/neutron/extensions/loadbalancer.py b/neutron/extensions/loadbalancer.py deleted file mode 100644 index ae91b6515..000000000 --- a/neutron/extensions/loadbalancer.py +++ /dev/null @@ -1,506 +0,0 @@ -# Copyright 2012 OpenStack Foundation. -# 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. - -import abc - -from oslo.config import cfg -import six - -from neutron.api import extensions -from neutron.api.v2 import attributes as attr -from neutron.api.v2 import base -from neutron.api.v2 import resource_helper -from neutron.common import exceptions as qexception -from neutron import manager -from neutron.plugins.common import constants -from neutron.services import service_base - - -# Loadbalancer Exceptions -class DelayOrTimeoutInvalid(qexception.BadRequest): - message = _("Delay must be greater than or equal to timeout") - - -class NoEligibleBackend(qexception.NotFound): - message = _("No eligible backend for pool %(pool_id)s") - - -class VipNotFound(qexception.NotFound): - message = _("Vip %(vip_id)s could not be found") - - -class VipExists(qexception.NeutronException): - message = _("Another Vip already exists for pool %(pool_id)s") - - -class PoolNotFound(qexception.NotFound): - message = _("Pool %(pool_id)s could not be found") - - -class MemberNotFound(qexception.NotFound): - message = _("Member %(member_id)s could not be found") - - -class HealthMonitorNotFound(qexception.NotFound): - message = _("Health_monitor %(monitor_id)s could not be found") - - -class PoolMonitorAssociationNotFound(qexception.NotFound): - message = _("Monitor %(monitor_id)s is not associated " - "with Pool %(pool_id)s") - - -class PoolMonitorAssociationExists(qexception.Conflict): - message = _('health_monitor %(monitor_id)s is already associated ' - 'with pool %(pool_id)s') - - -class StateInvalid(qexception.NeutronException): - message = _("Invalid state %(state)s of Loadbalancer resource %(id)s") - - -class PoolInUse(qexception.InUse): - message = _("Pool %(pool_id)s is still in use") - - -class HealthMonitorInUse(qexception.InUse): - message = _("Health monitor %(monitor_id)s still has associations with " - "pools") - - -class PoolStatsNotFound(qexception.NotFound): - message = _("Statistics of Pool %(pool_id)s could not be found") - - -class ProtocolMismatch(qexception.BadRequest): - message = _("Protocol %(vip_proto)s does not match " - "pool protocol %(pool_proto)s") - - -class MemberExists(qexception.NeutronException): - message = _("Member with address %(address)s and port %(port)s " - "already present in pool %(pool)s") - - -RESOURCE_ATTRIBUTE_MAP = { - 'vips': { - 'id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True, - 'primary_key': True}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'required_by_policy': True, - 'is_visible': True}, - 'name': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'default': '', - 'is_visible': True}, - 'description': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'subnet_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True}, - 'address': {'allow_post': True, 'allow_put': False, - 'default': attr.ATTR_NOT_SPECIFIED, - 'validate': {'type:ip_address_or_none': None}, - 'is_visible': True}, - 'port_id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True}, - 'protocol_port': {'allow_post': True, 'allow_put': False, - 'validate': {'type:range': [0, 65535]}, - 'convert_to': attr.convert_to_int, - 'is_visible': True}, - 'protocol': {'allow_post': True, 'allow_put': False, - 'validate': {'type:values': ['TCP', 'HTTP', 'HTTPS']}, - 'is_visible': True}, - 'pool_id': {'allow_post': True, 'allow_put': True, - 'validate': {'type:uuid': None}, - 'is_visible': True}, - 'session_persistence': {'allow_post': True, 'allow_put': True, - 'convert_to': attr.convert_none_to_empty_dict, - 'default': {}, - 'validate': { - 'type:dict_or_empty': { - 'type': {'type:values': ['APP_COOKIE', - 'HTTP_COOKIE', - 'SOURCE_IP'], - 'required': True}, - 'cookie_name': {'type:string': None, - 'required': False}}}, - 'is_visible': True}, - 'connection_limit': {'allow_post': True, 'allow_put': True, - 'default': -1, - 'convert_to': attr.convert_to_int, - 'is_visible': True}, - 'admin_state_up': {'allow_post': True, 'allow_put': True, - 'default': True, - 'convert_to': attr.convert_to_boolean, - 'is_visible': True}, - 'status': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - 'status_description': {'allow_post': False, 'allow_put': False, - 'is_visible': True} - }, - 'pools': { - 'id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True, - 'primary_key': True}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'required_by_policy': True, - 'is_visible': True}, - 'vip_id': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - 'name': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'default': '', - 'is_visible': True}, - 'description': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'subnet_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True}, - 'protocol': {'allow_post': True, 'allow_put': False, - 'validate': {'type:values': ['TCP', 'HTTP', 'HTTPS']}, - 'is_visible': True}, - 'provider': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': attr.ATTR_NOT_SPECIFIED}, - 'lb_method': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True}, - 'members': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - 'health_monitors': {'allow_post': True, 'allow_put': True, - 'default': None, - 'validate': {'type:uuid_list': None}, - 'convert_to': attr.convert_to_list, - 'is_visible': True}, - 'health_monitors_status': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - 'admin_state_up': {'allow_post': True, 'allow_put': True, - 'default': True, - 'convert_to': attr.convert_to_boolean, - 'is_visible': True}, - 'status': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - 'status_description': {'allow_post': False, 'allow_put': False, - 'is_visible': True} - }, - 'members': { - 'id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True, - 'primary_key': True}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'required_by_policy': True, - 'is_visible': True}, - 'pool_id': {'allow_post': True, 'allow_put': True, - 'validate': {'type:uuid': None}, - 'is_visible': True}, - 'address': {'allow_post': True, 'allow_put': False, - 'validate': {'type:ip_address': None}, - 'is_visible': True}, - 'protocol_port': {'allow_post': True, 'allow_put': False, - 'validate': {'type:range': [0, 65535]}, - 'convert_to': attr.convert_to_int, - 'is_visible': True}, - 'weight': {'allow_post': True, 'allow_put': True, - 'default': 1, - 'validate': {'type:range': [0, 256]}, - 'convert_to': attr.convert_to_int, - 'is_visible': True}, - 'admin_state_up': {'allow_post': True, 'allow_put': True, - 'default': True, - 'convert_to': attr.convert_to_boolean, - 'is_visible': True}, - 'status': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - 'status_description': {'allow_post': False, 'allow_put': False, - 'is_visible': True} - }, - 'health_monitors': { - 'id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True, - 'primary_key': True}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'required_by_policy': True, - 'is_visible': True}, - 'type': {'allow_post': True, 'allow_put': False, - 'validate': {'type:values': ['PING', 'TCP', 'HTTP', 'HTTPS']}, - 'is_visible': True}, - 'delay': {'allow_post': True, 'allow_put': True, - 'validate': {'type:non_negative': None}, - 'convert_to': attr.convert_to_int, - 'is_visible': True}, - 'timeout': {'allow_post': True, 'allow_put': True, - 'validate': {'type:non_negative': None}, - 'convert_to': attr.convert_to_int, - 'is_visible': True}, - 'max_retries': {'allow_post': True, 'allow_put': True, - 'validate': {'type:range': [1, 10]}, - 'convert_to': attr.convert_to_int, - 'is_visible': True}, - 'http_method': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'default': 'GET', - 'is_visible': True}, - 'url_path': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'default': '/', - 'is_visible': True}, - 'expected_codes': {'allow_post': True, 'allow_put': True, - 'validate': { - 'type:regex': - '^(\d{3}(\s*,\s*\d{3})*)$|^(\d{3}-\d{3})$'}, - 'default': '200', - 'is_visible': True}, - 'admin_state_up': {'allow_post': True, 'allow_put': True, - 'default': True, - 'convert_to': attr.convert_to_boolean, - 'is_visible': True}, - 'status': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - 'status_description': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - 'pools': {'allow_post': False, 'allow_put': False, - 'is_visible': True} - } -} - -SUB_RESOURCE_ATTRIBUTE_MAP = { - 'health_monitors': { - 'parent': {'collection_name': 'pools', - 'member_name': 'pool'}, - 'parameters': {'id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'required_by_policy': True, - 'is_visible': True}, - } - } -} - -lbaas_quota_opts = [ - cfg.IntOpt('quota_vip', - default=10, - help=_('Number of vips allowed per tenant. ' - 'A negative value means unlimited.')), - cfg.IntOpt('quota_pool', - default=10, - help=_('Number of pools allowed per tenant. ' - 'A negative value means unlimited.')), - cfg.IntOpt('quota_member', - default=-1, - help=_('Number of pool members allowed per tenant. ' - 'A negative value means unlimited.')), - cfg.IntOpt('quota_health_monitor', - default=-1, - help=_('Number of health monitors allowed per tenant. ' - 'A negative value means unlimited.')) -] -cfg.CONF.register_opts(lbaas_quota_opts, 'QUOTAS') - - -class Loadbalancer(extensions.ExtensionDescriptor): - - @classmethod - def get_name(cls): - return "LoadBalancing service" - - @classmethod - def get_alias(cls): - return "lbaas" - - @classmethod - def get_description(cls): - return "Extension for LoadBalancing service" - - @classmethod - def get_namespace(cls): - return "http://wiki.openstack.org/neutron/LBaaS/API_1.0" - - @classmethod - def get_updated(cls): - return "2012-10-07T10:00:00-00:00" - - @classmethod - def get_resources(cls): - plural_mappings = resource_helper.build_plural_mappings( - {}, RESOURCE_ATTRIBUTE_MAP) - plural_mappings['health_monitors_status'] = 'health_monitor_status' - attr.PLURALS.update(plural_mappings) - action_map = {'pool': {'stats': 'GET'}} - resources = resource_helper.build_resource_info(plural_mappings, - RESOURCE_ATTRIBUTE_MAP, - constants.LOADBALANCER, - action_map=action_map, - register_quota=True) - plugin = manager.NeutronManager.get_service_plugins()[ - constants.LOADBALANCER] - for collection_name in SUB_RESOURCE_ATTRIBUTE_MAP: - # Special handling needed for sub-resources with 'y' ending - # (e.g. proxies -> proxy) - resource_name = collection_name[:-1] - parent = SUB_RESOURCE_ATTRIBUTE_MAP[collection_name].get('parent') - params = SUB_RESOURCE_ATTRIBUTE_MAP[collection_name].get( - 'parameters') - - controller = base.create_resource(collection_name, resource_name, - plugin, params, - allow_bulk=True, - parent=parent) - - resource = extensions.ResourceExtension( - collection_name, - controller, parent, - path_prefix=constants.COMMON_PREFIXES[constants.LOADBALANCER], - attr_map=params) - resources.append(resource) - - return resources - - @classmethod - def get_plugin_interface(cls): - return LoadBalancerPluginBase - - def update_attributes_map(self, attributes): - super(Loadbalancer, self).update_attributes_map( - attributes, extension_attrs_map=RESOURCE_ATTRIBUTE_MAP) - - def get_extended_resources(self, version): - if version == "2.0": - return RESOURCE_ATTRIBUTE_MAP - else: - return {} - - -@six.add_metaclass(abc.ABCMeta) -class LoadBalancerPluginBase(service_base.ServicePluginBase): - - def get_plugin_name(self): - return constants.LOADBALANCER - - def get_plugin_type(self): - return constants.LOADBALANCER - - def get_plugin_description(self): - return 'LoadBalancer service plugin' - - @abc.abstractmethod - def get_vips(self, context, filters=None, fields=None): - pass - - @abc.abstractmethod - def get_vip(self, context, id, fields=None): - pass - - @abc.abstractmethod - def create_vip(self, context, vip): - pass - - @abc.abstractmethod - def update_vip(self, context, id, vip): - pass - - @abc.abstractmethod - def delete_vip(self, context, id): - pass - - @abc.abstractmethod - def get_pools(self, context, filters=None, fields=None): - pass - - @abc.abstractmethod - def get_pool(self, context, id, fields=None): - pass - - @abc.abstractmethod - def create_pool(self, context, pool): - pass - - @abc.abstractmethod - def update_pool(self, context, id, pool): - pass - - @abc.abstractmethod - def delete_pool(self, context, id): - pass - - @abc.abstractmethod - def stats(self, context, pool_id): - pass - - @abc.abstractmethod - def create_pool_health_monitor(self, context, health_monitor, pool_id): - pass - - @abc.abstractmethod - def get_pool_health_monitor(self, context, id, pool_id, fields=None): - pass - - @abc.abstractmethod - def delete_pool_health_monitor(self, context, id, pool_id): - pass - - @abc.abstractmethod - def get_members(self, context, filters=None, fields=None): - pass - - @abc.abstractmethod - def get_member(self, context, id, fields=None): - pass - - @abc.abstractmethod - def create_member(self, context, member): - pass - - @abc.abstractmethod - def update_member(self, context, id, member): - pass - - @abc.abstractmethod - def delete_member(self, context, id): - pass - - @abc.abstractmethod - def get_health_monitors(self, context, filters=None, fields=None): - pass - - @abc.abstractmethod - def get_health_monitor(self, context, id, fields=None): - pass - - @abc.abstractmethod - def create_health_monitor(self, context, health_monitor): - pass - - @abc.abstractmethod - def update_health_monitor(self, context, id, health_monitor): - pass - - @abc.abstractmethod - def delete_health_monitor(self, context, id): - pass diff --git a/neutron/extensions/metering.py b/neutron/extensions/metering.py deleted file mode 100644 index 02aefc86b..000000000 --- a/neutron/extensions/metering.py +++ /dev/null @@ -1,190 +0,0 @@ -# Copyright (C) 2013 eNovance SAS -# -# Author: Sylvain Afchain -# -# 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 abc - -import six - -from neutron.api import extensions -from neutron.api.v2 import attributes as attr -from neutron.api.v2 import resource_helper -from neutron.common import exceptions as qexception -from neutron.openstack.common import log as logging -from neutron.plugins.common import constants -from neutron.services import service_base - -LOG = logging.getLogger(__name__) - - -class MeteringLabelNotFound(qexception.NotFound): - message = _("Metering label %(label_id)s does not exist") - - -class DuplicateMeteringRuleInPost(qexception.InUse): - message = _("Duplicate Metering Rule in POST.") - - -class MeteringLabelRuleNotFound(qexception.NotFound): - message = _("Metering label rule %(rule_id)s does not exist") - - -class MeteringLabelRuleOverlaps(qexception.NotFound): - message = _("Metering label rule with remote_ip_prefix " - "%(remote_ip_prefix)s overlaps another") - - -RESOURCE_ATTRIBUTE_MAP = { - 'metering_labels': { - 'id': {'allow_post': False, 'allow_put': False, - 'is_visible': True, - 'primary_key': True}, - 'name': {'allow_post': True, 'allow_put': True, - 'is_visible': True, 'default': ''}, - 'description': {'allow_post': True, 'allow_put': True, - 'is_visible': True, 'default': ''}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'required_by_policy': True, - 'is_visible': True} - }, - 'metering_label_rules': { - 'id': {'allow_post': False, 'allow_put': False, - 'is_visible': True, - 'primary_key': True}, - 'metering_label_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True, 'required_by_policy': True}, - 'direction': {'allow_post': True, 'allow_put': True, - 'is_visible': True, - 'validate': {'type:values': ['ingress', 'egress']}}, - 'excluded': {'allow_post': True, 'allow_put': True, - 'is_visible': True, 'default': False, - 'convert_to': attr.convert_to_boolean}, - 'remote_ip_prefix': {'allow_post': True, 'allow_put': False, - 'is_visible': True, 'required_by_policy': True, - 'validate': {'type:subnet': None}}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'required_by_policy': True, - 'is_visible': True} - } -} - - -class Metering(extensions.ExtensionDescriptor): - - @classmethod - def get_name(cls): - return "Neutron Metering" - - @classmethod - def get_alias(cls): - return "metering" - - @classmethod - def get_description(cls): - return "Neutron Metering extension." - - @classmethod - def get_namespace(cls): - return "http://wiki.openstack.org/wiki/Neutron/Metering/Bandwidth#API" - - @classmethod - def get_updated(cls): - return "2013-06-12T10:00:00-00:00" - - @classmethod - def get_plugin_interface(cls): - return MeteringPluginBase - - @classmethod - def get_resources(cls): - """Returns Ext Resources.""" - plural_mappings = resource_helper.build_plural_mappings( - {}, RESOURCE_ATTRIBUTE_MAP) - attr.PLURALS.update(plural_mappings) - # PCM: Metering sets pagination and sorting to True. Do we have cfg - # entries for these so can be read? Else, must pass in. - return resource_helper.build_resource_info(plural_mappings, - RESOURCE_ATTRIBUTE_MAP, - constants.METERING, - translate_name=True, - allow_bulk=True) - - def update_attributes_map(self, attributes): - super(Metering, self).update_attributes_map( - attributes, extension_attrs_map=RESOURCE_ATTRIBUTE_MAP) - - def get_extended_resources(self, version): - if version == "2.0": - return RESOURCE_ATTRIBUTE_MAP - else: - return {} - - -@six.add_metaclass(abc.ABCMeta) -class MeteringPluginBase(service_base.ServicePluginBase): - - def get_plugin_name(self): - return constants.METERING - - def get_plugin_description(self): - return constants.METERING - - def get_plugin_type(self): - return constants.METERING - - @abc.abstractmethod - def create_metering_label(self, context, metering_label): - """Create a metering label.""" - pass - - @abc.abstractmethod - def delete_metering_label(self, context, label_id): - """Delete a metering label.""" - pass - - @abc.abstractmethod - def get_metering_label(self, context, label_id, fields=None): - """Get a metering label.""" - pass - - @abc.abstractmethod - def get_metering_labels(self, context, filters=None, fields=None, - sorts=None, limit=None, marker=None, - page_reverse=False): - """List all metering labels.""" - pass - - @abc.abstractmethod - def create_metering_label_rule(self, context, metering_label_rule): - """Create a metering label rule.""" - pass - - @abc.abstractmethod - def get_metering_label_rule(self, context, rule_id, fields=None): - """Get a metering label rule.""" - pass - - @abc.abstractmethod - def delete_metering_label_rule(self, context, rule_id): - """Delete a metering label rule.""" - pass - - @abc.abstractmethod - def get_metering_label_rules(self, context, filters=None, fields=None, - sorts=None, limit=None, marker=None, - page_reverse=False): - """List all metering label rules.""" - pass diff --git a/neutron/extensions/multiprovidernet.py b/neutron/extensions/multiprovidernet.py deleted file mode 100644 index 79fcb9e4a..000000000 --- a/neutron/extensions/multiprovidernet.py +++ /dev/null @@ -1,114 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation. -# 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. - -import webob.exc - -from neutron.api import extensions -from neutron.api.v2 import attributes as attr -from neutron.common import exceptions as qexception -from neutron.extensions import providernet as pnet - -SEGMENTS = 'segments' - - -class SegmentsSetInConjunctionWithProviders(qexception.InvalidInput): - message = _("Segments and provider values cannot both be set.") - - -class SegmentsContainDuplicateEntry(qexception.InvalidInput): - message = _("Duplicate segment entry in request.") - - -def _convert_and_validate_segments(segments, valid_values=None): - unique = set() - for segment in segments: - unique.add(tuple(segment.iteritems())) - network_type = segment.get(pnet.NETWORK_TYPE, - attr.ATTR_NOT_SPECIFIED) - segment[pnet.NETWORK_TYPE] = network_type - physical_network = segment.get(pnet.PHYSICAL_NETWORK, - attr.ATTR_NOT_SPECIFIED) - segment[pnet.PHYSICAL_NETWORK] = physical_network - segmentation_id = segment.get(pnet.SEGMENTATION_ID) - if segmentation_id: - segment[pnet.SEGMENTATION_ID] = attr.convert_to_int( - segmentation_id) - else: - segment[pnet.SEGMENTATION_ID] = attr.ATTR_NOT_SPECIFIED - if len(segment.keys()) != 3: - msg = (_("Unrecognized attribute(s) '%s'") % - ', '.join(set(segment.keys()) - - set([pnet.NETWORK_TYPE, pnet.PHYSICAL_NETWORK, - pnet.SEGMENTATION_ID]))) - raise webob.exc.HTTPBadRequest(msg) - if len(unique) != len(segments): - raise SegmentsContainDuplicateEntry() - - -attr.validators['type:convert_segments'] = ( - _convert_and_validate_segments) - - -EXTENDED_ATTRIBUTES_2_0 = { - 'networks': { - SEGMENTS: {'allow_post': True, 'allow_put': True, - 'validate': {'type:convert_segments': None}, - 'convert_list_to': attr.convert_kvp_list_to_dict, - 'default': attr.ATTR_NOT_SPECIFIED, - 'enforce_policy': True, - 'is_visible': True}, - } -} - - -class Multiprovidernet(extensions.ExtensionDescriptor): - """Extension class supporting multiple provider networks. - - This class is used by neutron's extension framework to make - metadata about the multiple provider network extension available to - clients. No new resources are defined by this extension. Instead, - the existing network resource's request and response messages are - extended with 'segments' attribute. - - With admin rights, network dictionaries returned will also include - 'segments' attribute. - """ - - @classmethod - def get_name(cls): - return "Multi Provider Network" - - @classmethod - def get_alias(cls): - return "multi-provider" - - @classmethod - def get_description(cls): - return ("Expose mapping of virtual networks to multiple physical " - "networks") - - @classmethod - def get_namespace(cls): - return "http://docs.openstack.org/ext/multi-provider/api/v1.0" - - @classmethod - def get_updated(cls): - return "2013-06-27T10:00:00-00:00" - - def get_extended_resources(self, version): - if version == "2.0": - return EXTENDED_ATTRIBUTES_2_0 - else: - return {} diff --git a/neutron/extensions/portbindings.py b/neutron/extensions/portbindings.py deleted file mode 100644 index 7e5c76dd3..000000000 --- a/neutron/extensions/portbindings.py +++ /dev/null @@ -1,133 +0,0 @@ -# Copyright (c) 2012 OpenStack Foundation. -# 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. - -from neutron.api import extensions -from neutron.api.v2 import attributes - -# The type of vnic that this port should be attached to -VNIC_TYPE = 'binding:vnic_type' -# The service will return the vif type for the specific port. -VIF_TYPE = 'binding:vif_type' -# The service may return a dictionary containing additional -# information needed by the interface driver. The set of items -# returned may depend on the value of VIF_TYPE. -VIF_DETAILS = 'binding:vif_details' -# In some cases different implementations may be run on different hosts. -# The host on which the port will be allocated. -HOST_ID = 'binding:host_id' -# The profile will be a dictionary that enables the application running -# on the specific host to pass and receive vif port specific information to -# the plugin. -PROFILE = 'binding:profile' - -# The keys below are used in the VIF_DETAILS attribute to convey -# information to the VIF driver. - -# TODO(rkukura): Replace CAP_PORT_FILTER, which nova no longer -# understands, with the new set of VIF security details to be used in -# the VIF_DETAILS attribute. -# -# - port_filter : Boolean value indicating Neutron provides port filtering -# features such as security group and anti MAC/IP spoofing -# - ovs_hybrid_plug: Boolean used to inform Nova that the hybrid plugging -# strategy for OVS should be used -CAP_PORT_FILTER = 'port_filter' -OVS_HYBRID_PLUG = 'ovs_hybrid_plug' - -VIF_TYPE_UNBOUND = 'unbound' -VIF_TYPE_BINDING_FAILED = 'binding_failed' -VIF_TYPE_IOVISOR = 'iovisor' -VIF_TYPE_OVS = 'ovs' -VIF_TYPE_IVS = 'ivs' -VIF_TYPE_BRIDGE = 'bridge' -VIF_TYPE_802_QBG = '802.1qbg' -VIF_TYPE_802_QBH = '802.1qbh' -VIF_TYPE_HYPERV = 'hyperv' -VIF_TYPE_MIDONET = 'midonet' -VIF_TYPE_MLNX_DIRECT = 'mlnx_direct' -VIF_TYPE_MLNX_HOSTDEV = 'hostdev' -VIF_TYPE_OTHER = 'other' -VIF_TYPES = [VIF_TYPE_UNBOUND, VIF_TYPE_BINDING_FAILED, VIF_TYPE_OVS, - VIF_TYPE_IVS, VIF_TYPE_BRIDGE, VIF_TYPE_802_QBG, - VIF_TYPE_802_QBH, VIF_TYPE_HYPERV, VIF_TYPE_MIDONET, - VIF_TYPE_MLNX_DIRECT, VIF_TYPE_MLNX_HOSTDEV, VIF_TYPE_OTHER] - -VNIC_NORMAL = 'normal' -VNIC_DIRECT = 'direct' -VNIC_MACVTAP = 'macvtap' -VNIC_TYPES = [VNIC_NORMAL, VNIC_DIRECT, VNIC_MACVTAP] - -EXTENDED_ATTRIBUTES_2_0 = { - 'ports': { - VIF_TYPE: {'allow_post': False, 'allow_put': False, - 'default': attributes.ATTR_NOT_SPECIFIED, - 'enforce_policy': True, - 'is_visible': True}, - VIF_DETAILS: {'allow_post': False, 'allow_put': False, - 'default': attributes.ATTR_NOT_SPECIFIED, - 'enforce_policy': True, - 'is_visible': True}, - VNIC_TYPE: {'allow_post': True, 'allow_put': True, - 'default': VNIC_NORMAL, - 'is_visible': True, - 'validate': {'type:values': VNIC_TYPES}, - 'enforce_policy': True}, - HOST_ID: {'allow_post': True, 'allow_put': True, - 'default': attributes.ATTR_NOT_SPECIFIED, - 'is_visible': True, - 'enforce_policy': True}, - PROFILE: {'allow_post': True, 'allow_put': True, - 'default': attributes.ATTR_NOT_SPECIFIED, - 'enforce_policy': True, - 'validate': {'type:dict_or_none': None}, - 'is_visible': True}, - } -} - - -class Portbindings(extensions.ExtensionDescriptor): - """Extension class supporting port bindings. - - This class is used by neutron's extension framework to make - metadata about the port bindings available to external applications. - - With admin rights one will be able to update and read the values. - """ - - @classmethod - def get_name(cls): - return "Port Binding" - - @classmethod - def get_alias(cls): - return "binding" - - @classmethod - def get_description(cls): - return "Expose port bindings of a virtual port to external application" - - @classmethod - def get_namespace(cls): - return "http://docs.openstack.org/ext/binding/api/v1.0" - - @classmethod - def get_updated(cls): - return "2014-02-03T10:00:00-00:00" - - def get_extended_resources(self, version): - if version == "2.0": - return EXTENDED_ATTRIBUTES_2_0 - else: - return {} diff --git a/neutron/extensions/portsecurity.py b/neutron/extensions/portsecurity.py deleted file mode 100644 index b652436ed..000000000 --- a/neutron/extensions/portsecurity.py +++ /dev/null @@ -1,78 +0,0 @@ -# Copyright 2013 VMware, 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. - -from neutron.api.v2 import attributes -from neutron.common import exceptions as qexception - - -class PortSecurityPortHasSecurityGroup(qexception.InUse): - message = _("Port has security group associated. Cannot disable port " - "security or ip address until security group is removed") - - -class PortSecurityAndIPRequiredForSecurityGroups(qexception.InvalidInput): - message = _("Port security must be enabled and port must have an IP" - " address in order to use security groups.") - - -class PortSecurityBindingNotFound(qexception.InvalidExtensionEnv): - message = _("Port does not have port security binding.") - -PORTSECURITY = 'port_security_enabled' -EXTENDED_ATTRIBUTES_2_0 = { - 'networks': { - PORTSECURITY: {'allow_post': True, 'allow_put': True, - 'convert_to': attributes.convert_to_boolean, - 'enforce_policy': True, - 'default': True, - 'is_visible': True}, - }, - 'ports': { - PORTSECURITY: {'allow_post': True, 'allow_put': True, - 'convert_to': attributes.convert_to_boolean, - 'default': attributes.ATTR_NOT_SPECIFIED, - 'enforce_policy': True, - 'is_visible': True}, - } -} - - -class Portsecurity(object): - """Extension class supporting port security.""" - - @classmethod - def get_name(cls): - return "Port Security" - - @classmethod - def get_alias(cls): - return "port-security" - - @classmethod - def get_description(cls): - return "Provides port security" - - @classmethod - def get_namespace(cls): - return "http://docs.openstack.org/ext/portsecurity/api/v1.0" - - @classmethod - def get_updated(cls): - return "2012-07-23T10:00:00-00:00" - - def get_extended_resources(self, version): - if version == "2.0": - return EXTENDED_ATTRIBUTES_2_0 - else: - return {} diff --git a/neutron/extensions/providernet.py b/neutron/extensions/providernet.py deleted file mode 100644 index 944de104f..000000000 --- a/neutron/extensions/providernet.py +++ /dev/null @@ -1,95 +0,0 @@ -# Copyright (c) 2012 OpenStack Foundation. -# 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. - -from neutron.api import extensions -from neutron.api.v2 import attributes -from neutron.common import exceptions as n_exc - - -NETWORK_TYPE = 'provider:network_type' -PHYSICAL_NETWORK = 'provider:physical_network' -SEGMENTATION_ID = 'provider:segmentation_id' - -EXTENDED_ATTRIBUTES_2_0 = { - 'networks': { - NETWORK_TYPE: {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'default': attributes.ATTR_NOT_SPECIFIED, - 'enforce_policy': True, - 'is_visible': True}, - PHYSICAL_NETWORK: {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'default': attributes.ATTR_NOT_SPECIFIED, - 'enforce_policy': True, - 'is_visible': True}, - SEGMENTATION_ID: {'allow_post': True, 'allow_put': True, - 'convert_to': int, - 'enforce_policy': True, - 'default': attributes.ATTR_NOT_SPECIFIED, - 'is_visible': True}, - } -} - - -def _raise_if_updates_provider_attributes(attrs): - """Raise exception if provider attributes are present. - - This method is used for plugins that do not support - updating provider networks. - """ - immutable = (NETWORK_TYPE, PHYSICAL_NETWORK, SEGMENTATION_ID) - if any(attributes.is_attr_set(attrs.get(a)) for a in immutable): - msg = _("Plugin does not support updating provider attributes") - raise n_exc.InvalidInput(error_message=msg) - - -class Providernet(extensions.ExtensionDescriptor): - """Extension class supporting provider networks. - - This class is used by neutron's extension framework to make - metadata about the provider network extension available to - clients. No new resources are defined by this extension. Instead, - the existing network resource's request and response messages are - extended with attributes in the provider namespace. - - With admin rights, network dictionaries returned will also include - provider attributes. - """ - - @classmethod - def get_name(cls): - return "Provider Network" - - @classmethod - def get_alias(cls): - return "provider" - - @classmethod - def get_description(cls): - return "Expose mapping of virtual networks to physical networks" - - @classmethod - def get_namespace(cls): - return "http://docs.openstack.org/ext/provider/api/v1.0" - - @classmethod - def get_updated(cls): - return "2012-09-07T10:00:00-00:00" - - def get_extended_resources(self, version): - if version == "2.0": - return EXTENDED_ATTRIBUTES_2_0 - else: - return {} diff --git a/neutron/extensions/quotasv2.py b/neutron/extensions/quotasv2.py deleted file mode 100644 index 4fa9bf280..000000000 --- a/neutron/extensions/quotasv2.py +++ /dev/null @@ -1,152 +0,0 @@ -# Copyright 2011 OpenStack Foundation. -# 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. - -import sys - -from oslo.config import cfg -import webob - -from neutron.api import extensions -from neutron.api.v2 import attributes -from neutron.api.v2 import base -from neutron.api.v2 import resource -from neutron.common import exceptions as n_exc -from neutron import manager -from neutron.openstack.common import importutils -from neutron import quota -from neutron import wsgi - - -RESOURCE_NAME = 'quota' -RESOURCE_COLLECTION = RESOURCE_NAME + "s" -QUOTAS = quota.QUOTAS -DB_QUOTA_DRIVER = 'neutron.db.quota_db.DbQuotaDriver' -EXTENDED_ATTRIBUTES_2_0 = { - RESOURCE_COLLECTION: {} -} - - -class QuotaSetsController(wsgi.Controller): - - def __init__(self, plugin): - self._resource_name = RESOURCE_NAME - self._plugin = plugin - self._driver = importutils.import_class( - cfg.CONF.QUOTAS.quota_driver - ) - self._update_extended_attributes = True - - def _update_attributes(self): - for quota_resource in QUOTAS.resources.iterkeys(): - attr_dict = EXTENDED_ATTRIBUTES_2_0[RESOURCE_COLLECTION] - attr_dict[quota_resource] = { - 'allow_post': False, - 'allow_put': True, - 'convert_to': attributes.convert_to_int, - 'validate': {'type:range': [-1, sys.maxsize]}, - 'is_visible': True} - self._update_extended_attributes = False - - def _get_quotas(self, request, tenant_id): - return self._driver.get_tenant_quotas( - request.context, QUOTAS.resources, tenant_id) - - def create(self, request, body=None): - msg = _('POST requests are not supported on this resource.') - raise webob.exc.HTTPNotImplemented(msg) - - def index(self, request): - context = request.context - self._check_admin(context) - return {self._resource_name + "s": - self._driver.get_all_quotas(context, QUOTAS.resources)} - - def tenant(self, request): - """Retrieve the tenant info in context.""" - context = request.context - if not context.tenant_id: - raise n_exc.QuotaMissingTenant() - return {'tenant': {'tenant_id': context.tenant_id}} - - def show(self, request, id): - if id != request.context.tenant_id: - self._check_admin(request.context, - reason=_("Only admin is authorized " - "to access quotas for another tenant")) - return {self._resource_name: self._get_quotas(request, id)} - - def _check_admin(self, context, - reason=_("Only admin can view or configure quota")): - if not context.is_admin: - raise n_exc.AdminRequired(reason=reason) - - def delete(self, request, id): - self._check_admin(request.context) - self._driver.delete_tenant_quota(request.context, id) - - def update(self, request, id, body=None): - self._check_admin(request.context) - if self._update_extended_attributes: - self._update_attributes() - body = base.Controller.prepare_request_body( - request.context, body, False, self._resource_name, - EXTENDED_ATTRIBUTES_2_0[RESOURCE_COLLECTION]) - for key, value in body[self._resource_name].items(): - self._driver.update_quota_limit(request.context, id, key, value) - return {self._resource_name: self._get_quotas(request, id)} - - -class Quotasv2(extensions.ExtensionDescriptor): - """Quotas management support.""" - - @classmethod - def get_name(cls): - return "Quota management support" - - @classmethod - def get_alias(cls): - return RESOURCE_COLLECTION - - @classmethod - def get_description(cls): - description = 'Expose functions for quotas management' - if cfg.CONF.QUOTAS.quota_driver == DB_QUOTA_DRIVER: - description += ' per tenant' - return description - - @classmethod - def get_namespace(cls): - return "http://docs.openstack.org/network/ext/quotas-sets/api/v2.0" - - @classmethod - def get_updated(cls): - return "2012-07-29T10:00:00-00:00" - - @classmethod - def get_resources(cls): - """Returns Ext Resources.""" - controller = resource.Resource( - QuotaSetsController(manager.NeutronManager.get_plugin()), - faults=base.FAULT_MAP) - return [extensions.ResourceExtension( - Quotasv2.get_alias(), - controller, - collection_actions={'tenant': 'GET'})] - - def get_extended_resources(self, version): - if version == "2.0": - return EXTENDED_ATTRIBUTES_2_0 - else: - return {} diff --git a/neutron/extensions/routedserviceinsertion.py b/neutron/extensions/routedserviceinsertion.py deleted file mode 100644 index 06ff9e259..000000000 --- a/neutron/extensions/routedserviceinsertion.py +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright 2013 VMware, 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: Kaiwei Fan, VMware, Inc - - -ROUTER_ID = 'router_id' -EXTENDED_ATTRIBUTES_2_0 = { - 'vips': { - ROUTER_ID: {'allow_post': True, 'allow_put': False, - 'validate': {'type:uuid_or_none': None}, - 'default': None, 'is_visible': True}, - }, - 'pools': { - ROUTER_ID: {'allow_post': True, 'allow_put': False, - 'validate': {'type:uuid_or_none': None}, - 'default': None, 'is_visible': True}, - }, - 'health_monitors': { - ROUTER_ID: {'allow_post': True, 'allow_put': False, - 'validate': {'type:uuid_or_none': None}, - 'default': None, 'is_visible': True}, - }, - - 'firewalls': { - ROUTER_ID: {'allow_post': True, 'allow_put': False, - 'validate': {'type:uuid_or_none': None}, - 'default': None, 'is_visible': True}, - } -} - - -class Routedserviceinsertion(object): - """Extension class supporting routed service type.""" - - @classmethod - def get_name(cls): - return "Routed Service Insertion" - - @classmethod - def get_alias(cls): - return "routed-service-insertion" - - @classmethod - def get_description(cls): - return "Provides routed service type" - - @classmethod - def get_namespace(cls): - return "" - - @classmethod - def get_updated(cls): - return "2013-01-29T00:00:00-00:00" - - def get_extended_resources(self, version): - if version == "2.0": - return EXTENDED_ATTRIBUTES_2_0 - else: - return {} diff --git a/neutron/extensions/routerservicetype.py b/neutron/extensions/routerservicetype.py deleted file mode 100644 index 6168adf36..000000000 --- a/neutron/extensions/routerservicetype.py +++ /dev/null @@ -1,55 +0,0 @@ -# Copyright 2013 VMware, 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: Kaiwei Fan, VMware, Inc - - -SERVICE_TYPE_ID = 'service_type_id' -EXTENDED_ATTRIBUTES_2_0 = { - 'routers': { - SERVICE_TYPE_ID: {'allow_post': True, 'allow_put': False, - 'validate': {'type:uuid_or_none': None}, - 'default': None, 'is_visible': True}, - } -} - - -class Routerservicetype(object): - """Extension class supporting router service type.""" - - @classmethod - def get_name(cls): - return "Router Service Type" - - @classmethod - def get_alias(cls): - return "router-service-type" - - @classmethod - def get_description(cls): - return "Provides router service type" - - @classmethod - def get_namespace(cls): - return "" - - @classmethod - def get_updated(cls): - return "2013-01-29T00:00:00-00:00" - - def get_extended_resources(self, version): - if version == "2.0": - return EXTENDED_ATTRIBUTES_2_0 - else: - return {} diff --git a/neutron/extensions/securitygroup.py b/neutron/extensions/securitygroup.py deleted file mode 100644 index 5f004af48..000000000 --- a/neutron/extensions/securitygroup.py +++ /dev/null @@ -1,354 +0,0 @@ -# Copyright (c) 2012 OpenStack Foundation. -# 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. - -import abc -import netaddr - -from oslo.config import cfg -import six - -from neutron.api import extensions -from neutron.api.v2 import attributes as attr -from neutron.api.v2 import base -from neutron.common import constants as const -from neutron.common import exceptions as qexception -from neutron import manager -from neutron.openstack.common import uuidutils -from neutron import quota - - -# Security group Exceptions -class SecurityGroupInvalidPortRange(qexception.InvalidInput): - message = _("For TCP/UDP protocols, port_range_min must be " - "<= port_range_max") - - -class SecurityGroupInvalidPortValue(qexception.InvalidInput): - message = _("Invalid value for port %(port)s") - - -class SecurityGroupInvalidIcmpValue(qexception.InvalidInput): - message = _("Invalid value for ICMP %(field)s (%(attr)s) " - "%(value)s. It must be 0 to 255.") - - -class SecurityGroupMissingIcmpType(qexception.InvalidInput): - message = _("ICMP code (port-range-max) %(value)s is provided" - " but ICMP type (port-range-min) is missing.") - - -class SecurityGroupInUse(qexception.InUse): - message = _("Security Group %(id)s in use.") - - -class SecurityGroupCannotRemoveDefault(qexception.InUse): - message = _("Removing default security group not allowed.") - - -class SecurityGroupCannotUpdateDefault(qexception.InUse): - message = _("Updating default security group not allowed.") - - -class SecurityGroupDefaultAlreadyExists(qexception.InUse): - message = _("Default security group already exists.") - - -class SecurityGroupRuleInvalidProtocol(qexception.InvalidInput): - message = _("Security group rule protocol %(protocol)s not supported. " - "Only protocol values %(values)s and their integer " - "representation (0 to 255) are supported.") - - -class SecurityGroupRulesNotSingleTenant(qexception.InvalidInput): - message = _("Multiple tenant_ids in bulk security group rule create" - " not allowed") - - -class SecurityGroupRemoteGroupAndRemoteIpPrefix(qexception.InvalidInput): - message = _("Only remote_ip_prefix or remote_group_id may " - "be provided.") - - -class SecurityGroupProtocolRequiredWithPorts(qexception.InvalidInput): - message = _("Must also specifiy protocol if port range is given.") - - -class SecurityGroupNotSingleGroupRules(qexception.InvalidInput): - message = _("Only allowed to update rules for " - "one security profile at a time") - - -class SecurityGroupNotFound(qexception.NotFound): - message = _("Security group %(id)s does not exist") - - -class SecurityGroupRuleNotFound(qexception.NotFound): - message = _("Security group rule %(id)s does not exist") - - -class DuplicateSecurityGroupRuleInPost(qexception.InUse): - message = _("Duplicate Security Group Rule in POST.") - - -class SecurityGroupRuleExists(qexception.InUse): - message = _("Security group rule already exists. Group id is %(id)s.") - - -class SecurityGroupRuleParameterConflict(qexception.InvalidInput): - message = _("Conflicting value ethertype %(ethertype)s for CIDR %(cidr)s") - - -def convert_protocol(value): - if value is None: - return - try: - val = int(value) - if val >= 0 and val <= 255: - return val - raise SecurityGroupRuleInvalidProtocol( - protocol=value, values=sg_supported_protocols) - except (ValueError, TypeError): - if value.lower() in sg_supported_protocols: - return value.lower() - raise SecurityGroupRuleInvalidProtocol( - protocol=value, values=sg_supported_protocols) - except AttributeError: - raise SecurityGroupRuleInvalidProtocol( - protocol=value, values=sg_supported_protocols) - - -def convert_ethertype_to_case_insensitive(value): - if isinstance(value, basestring): - for ethertype in sg_supported_ethertypes: - if ethertype.lower() == value.lower(): - return ethertype - - -def convert_validate_port_value(port): - if port is None: - return port - try: - val = int(port) - except (ValueError, TypeError): - raise SecurityGroupInvalidPortValue(port=port) - - if val >= 0 and val <= 65535: - return val - else: - raise SecurityGroupInvalidPortValue(port=port) - - -def convert_to_uuid_list_or_none(value_list): - if value_list is None: - return - for sg_id in value_list: - if not uuidutils.is_uuid_like(sg_id): - msg = _("'%s' is not an integer or uuid") % sg_id - raise qexception.InvalidInput(error_message=msg) - return value_list - - -def convert_ip_prefix_to_cidr(ip_prefix): - if not ip_prefix: - return - try: - cidr = netaddr.IPNetwork(ip_prefix) - return str(cidr) - except (ValueError, TypeError, netaddr.AddrFormatError): - raise qexception.InvalidCIDR(input=ip_prefix) - - -def _validate_name_not_default(data, valid_values=None): - if data == "default": - raise SecurityGroupDefaultAlreadyExists() - - -attr.validators['type:name_not_default'] = _validate_name_not_default - -sg_supported_protocols = [None, const.PROTO_NAME_TCP, - const.PROTO_NAME_UDP, const.PROTO_NAME_ICMP] -sg_supported_ethertypes = ['IPv4', 'IPv6'] - -# Attribute Map -RESOURCE_ATTRIBUTE_MAP = { - 'security_groups': { - 'id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True, - 'primary_key': True}, - 'name': {'allow_post': True, 'allow_put': True, - 'is_visible': True, 'default': '', - 'validate': {'type:name_not_default': None}}, - 'description': {'allow_post': True, 'allow_put': True, - 'is_visible': True, 'default': ''}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'required_by_policy': True, - 'is_visible': True}, - 'security_group_rules': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - }, - 'security_group_rules': { - 'id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True, - 'primary_key': True}, - 'security_group_id': {'allow_post': True, 'allow_put': False, - 'is_visible': True, 'required_by_policy': True}, - 'remote_group_id': {'allow_post': True, 'allow_put': False, - 'default': None, 'is_visible': True}, - 'direction': {'allow_post': True, 'allow_put': True, - 'is_visible': True, - 'validate': {'type:values': ['ingress', 'egress']}}, - 'protocol': {'allow_post': True, 'allow_put': False, - 'is_visible': True, 'default': None, - 'convert_to': convert_protocol}, - 'port_range_min': {'allow_post': True, 'allow_put': False, - 'convert_to': convert_validate_port_value, - 'default': None, 'is_visible': True}, - 'port_range_max': {'allow_post': True, 'allow_put': False, - 'convert_to': convert_validate_port_value, - 'default': None, 'is_visible': True}, - 'ethertype': {'allow_post': True, 'allow_put': False, - 'is_visible': True, 'default': 'IPv4', - 'convert_to': convert_ethertype_to_case_insensitive, - 'validate': {'type:values': sg_supported_ethertypes}}, - 'remote_ip_prefix': {'allow_post': True, 'allow_put': False, - 'default': None, 'is_visible': True, - 'convert_to': convert_ip_prefix_to_cidr}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'required_by_policy': True, - 'is_visible': True}, - } -} - - -SECURITYGROUPS = 'security_groups' -EXTENDED_ATTRIBUTES_2_0 = { - 'ports': {SECURITYGROUPS: {'allow_post': True, - 'allow_put': True, - 'is_visible': True, - 'convert_to': convert_to_uuid_list_or_none, - 'default': attr.ATTR_NOT_SPECIFIED}}} -security_group_quota_opts = [ - cfg.IntOpt('quota_security_group', - default=10, - help=_('Number of security groups allowed per tenant. ' - 'A negative value means unlimited.')), - cfg.IntOpt('quota_security_group_rule', - default=100, - help=_('Number of security rules allowed per tenant. ' - 'A negative value means unlimited.')), -] -cfg.CONF.register_opts(security_group_quota_opts, 'QUOTAS') - - -class Securitygroup(extensions.ExtensionDescriptor): - """Security group extension.""" - - @classmethod - def get_name(cls): - return "security-group" - - @classmethod - def get_alias(cls): - return "security-group" - - @classmethod - def get_description(cls): - return "The security groups extension." - - @classmethod - def get_namespace(cls): - # todo - return "http://docs.openstack.org/ext/securitygroups/api/v2.0" - - @classmethod - def get_updated(cls): - return "2012-10-05T10:00:00-00:00" - - @classmethod - def get_resources(cls): - """Returns Ext Resources.""" - my_plurals = [(key, key[:-1]) for key in RESOURCE_ATTRIBUTE_MAP.keys()] - attr.PLURALS.update(dict(my_plurals)) - exts = [] - plugin = manager.NeutronManager.get_plugin() - for resource_name in ['security_group', 'security_group_rule']: - collection_name = resource_name.replace('_', '-') + "s" - params = RESOURCE_ATTRIBUTE_MAP.get(resource_name + "s", dict()) - quota.QUOTAS.register_resource_by_name(resource_name) - controller = base.create_resource(collection_name, - resource_name, - plugin, params, allow_bulk=True, - allow_pagination=True, - allow_sorting=True) - - ex = extensions.ResourceExtension(collection_name, - controller, - attr_map=params) - exts.append(ex) - - return exts - - def get_extended_resources(self, version): - if version == "2.0": - return dict(EXTENDED_ATTRIBUTES_2_0.items() + - RESOURCE_ATTRIBUTE_MAP.items()) - else: - return {} - - -@six.add_metaclass(abc.ABCMeta) -class SecurityGroupPluginBase(object): - - @abc.abstractmethod - def create_security_group(self, context, security_group): - pass - - @abc.abstractmethod - def update_security_group(self, context, id, security_group): - pass - - @abc.abstractmethod - def delete_security_group(self, context, id): - pass - - @abc.abstractmethod - def get_security_groups(self, context, filters=None, fields=None, - sorts=None, limit=None, marker=None, - page_reverse=False): - pass - - @abc.abstractmethod - def get_security_group(self, context, id, fields=None): - pass - - @abc.abstractmethod - def create_security_group_rule(self, context, security_group_rule): - pass - - @abc.abstractmethod - def delete_security_group_rule(self, context, id): - pass - - @abc.abstractmethod - def get_security_group_rules(self, context, filters=None, fields=None, - sorts=None, limit=None, marker=None, - page_reverse=False): - pass - - @abc.abstractmethod - def get_security_group_rule(self, context, id, fields=None): - pass diff --git a/neutron/extensions/servicetype.py b/neutron/extensions/servicetype.py deleted file mode 100644 index 25633775d..000000000 --- a/neutron/extensions/servicetype.py +++ /dev/null @@ -1,91 +0,0 @@ -# Copyright 2013 OpenStack Foundation. -# 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: Salvatore Orlando, VMware -# - -from neutron.api import extensions -from neutron.api.v2 import attributes -from neutron.api.v2 import base -from neutron.db import servicetype_db -from neutron.openstack.common import log as logging - -LOG = logging.getLogger(__name__) - -RESOURCE_NAME = "service_provider" -COLLECTION_NAME = "%ss" % RESOURCE_NAME -SERVICE_ATTR = 'service_type' -PLUGIN_ATTR = 'plugin' -DRIVER_ATTR = 'driver' -EXT_ALIAS = 'service-type' - -# Attribute Map for Service Provider Resource -# Allow read-only access -RESOURCE_ATTRIBUTE_MAP = { - COLLECTION_NAME: { - 'service_type': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - 'name': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - 'default': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - } -} - - -class Servicetype(extensions.ExtensionDescriptor): - - @classmethod - def get_name(cls): - return _("Neutron Service Type Management") - - @classmethod - def get_alias(cls): - return EXT_ALIAS - - @classmethod - def get_description(cls): - return _("API for retrieving service providers for " - "Neutron advanced services") - - @classmethod - def get_namespace(cls): - return "http://docs.openstack.org/ext/neutron/service-type/api/v1.0" - - @classmethod - def get_updated(cls): - return "2013-01-20T00:00:00-00:00" - - @classmethod - def get_resources(cls): - """Returns Extended Resource for service type management.""" - my_plurals = [(key, key[:-1]) for key in RESOURCE_ATTRIBUTE_MAP.keys()] - attributes.PLURALS.update(dict(my_plurals)) - attr_map = RESOURCE_ATTRIBUTE_MAP[COLLECTION_NAME] - collection_name = COLLECTION_NAME.replace('_', '-') - controller = base.create_resource( - collection_name, - RESOURCE_NAME, - servicetype_db.ServiceTypeManager.get_instance(), - attr_map) - return [extensions.ResourceExtension(collection_name, - controller, - attr_map=attr_map)] - - def get_extended_resources(self, version): - if version == "2.0": - return RESOURCE_ATTRIBUTE_MAP - else: - return {} diff --git a/neutron/extensions/vpnaas.py b/neutron/extensions/vpnaas.py deleted file mode 100644 index f6bdcd761..000000000 --- a/neutron/extensions/vpnaas.py +++ /dev/null @@ -1,482 +0,0 @@ -# (c) Copyright 2013 Hewlett-Packard Development Company, L.P. -# 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: Swaminathan Vasudevan, Hewlett-Packard. - -import abc - -import six - -from neutron.api import extensions -from neutron.api.v2 import attributes as attr -from neutron.api.v2 import resource_helper -from neutron.common import exceptions as qexception -from neutron.plugins.common import constants -from neutron.services import service_base - - -class VPNServiceNotFound(qexception.NotFound): - message = _("VPNService %(vpnservice_id)s could not be found") - - -class IPsecSiteConnectionNotFound(qexception.NotFound): - message = _("ipsec_site_connection %(ipsecsite_conn_id)s not found") - - -class IPsecSiteConnectionDpdIntervalValueError(qexception.InvalidInput): - message = _("ipsec_site_connection %(attr)s is " - "equal to or less than dpd_interval") - - -class IPsecSiteConnectionMtuError(qexception.InvalidInput): - message = _("ipsec_site_connection MTU %(mtu)d is too small " - "for ipv%(version)s") - - -class IKEPolicyNotFound(qexception.NotFound): - message = _("IKEPolicy %(ikepolicy_id)s could not be found") - - -class IPsecPolicyNotFound(qexception.NotFound): - message = _("IPsecPolicy %(ipsecpolicy_id)s could not be found") - - -class IKEPolicyInUse(qexception.InUse): - message = _("IKEPolicy %(ikepolicy_id)s is in use by existing " - "IPsecSiteConnection and can't be updated or deleted") - - -class VPNServiceInUse(qexception.InUse): - message = _("VPNService %(vpnservice_id)s is still in use") - - -class RouterInUseByVPNService(qexception.InUse): - message = _("Router %(router_id)s is used by VPNService %(vpnservice_id)s") - - -class VPNStateInvalidToUpdate(qexception.BadRequest): - message = _("Invalid state %(state)s of vpnaas resource %(id)s" - " for updating") - - -class IPsecPolicyInUse(qexception.InUse): - message = _("IPsecPolicy %(ipsecpolicy_id)s is in use by existing " - "IPsecSiteConnection and can't be updated or deleted") - - -class DeviceDriverImportError(qexception.NeutronException): - message = _("Can not load driver :%(device_driver)s") - - -class SubnetIsNotConnectedToRouter(qexception.BadRequest): - message = _("Subnet %(subnet_id)s is not " - "connected to Router %(router_id)s") - - -class RouterIsNotExternal(qexception.BadRequest): - message = _("Router %(router_id)s has no external network gateway set") - - -vpn_supported_initiators = ['bi-directional', 'response-only'] -vpn_supported_encryption_algorithms = ['3des', 'aes-128', - 'aes-192', 'aes-256'] -vpn_dpd_supported_actions = [ - 'hold', 'clear', 'restart', 'restart-by-peer', 'disabled' -] -vpn_supported_transform_protocols = ['esp', 'ah', 'ah-esp'] -vpn_supported_encapsulation_mode = ['tunnel', 'transport'] -#TODO(nati) add kilobytes when we support it -vpn_supported_lifetime_units = ['seconds'] -vpn_supported_pfs = ['group2', 'group5', 'group14'] -vpn_supported_ike_versions = ['v1', 'v2'] -vpn_supported_auth_mode = ['psk'] -vpn_supported_auth_algorithms = ['sha1'] -vpn_supported_phase1_negotiation_mode = ['main'] - -vpn_lifetime_limits = (60, attr.UNLIMITED) -positive_int = (0, attr.UNLIMITED) - -RESOURCE_ATTRIBUTE_MAP = { - - 'vpnservices': { - 'id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True, - 'primary_key': True}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'required_by_policy': True, - 'is_visible': True}, - 'name': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'description': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'subnet_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True}, - 'router_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True}, - 'admin_state_up': {'allow_post': True, 'allow_put': True, - 'default': True, - 'convert_to': attr.convert_to_boolean, - 'is_visible': True}, - 'status': {'allow_post': False, 'allow_put': False, - 'is_visible': True} - }, - - 'ipsec_site_connections': { - 'id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True, - 'primary_key': True}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'required_by_policy': True, - 'is_visible': True}, - 'name': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'description': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'peer_address': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True}, - 'peer_id': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True}, - 'peer_cidrs': {'allow_post': True, 'allow_put': True, - 'convert_to': attr.convert_to_list, - 'validate': {'type:subnet_list': None}, - 'is_visible': True}, - 'route_mode': {'allow_post': False, 'allow_put': False, - 'default': 'static', - 'is_visible': True}, - 'mtu': {'allow_post': True, 'allow_put': True, - 'default': '1500', - 'validate': {'type:range': positive_int}, - 'convert_to': attr.convert_to_int, - 'is_visible': True}, - 'initiator': {'allow_post': True, 'allow_put': True, - 'default': 'bi-directional', - 'validate': {'type:values': vpn_supported_initiators}, - 'is_visible': True}, - 'auth_mode': {'allow_post': False, 'allow_put': False, - 'default': 'psk', - 'validate': {'type:values': vpn_supported_auth_mode}, - 'is_visible': True}, - 'psk': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True}, - 'dpd': {'allow_post': True, 'allow_put': True, - 'convert_to': attr.convert_none_to_empty_dict, - 'is_visible': True, - 'default': {}, - 'validate': { - 'type:dict_or_empty': { - 'actions': { - 'type:values': vpn_dpd_supported_actions, - }, - 'interval': { - 'type:range': positive_int - }, - 'timeout': { - 'type:range': positive_int - }}}}, - 'admin_state_up': {'allow_post': True, 'allow_put': True, - 'default': True, - 'convert_to': attr.convert_to_boolean, - 'is_visible': True}, - 'status': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - 'vpnservice_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True}, - 'ikepolicy_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True}, - 'ipsecpolicy_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True} - }, - - 'ipsecpolicies': { - 'id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True, - 'primary_key': True}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'required_by_policy': True, - 'is_visible': True}, - 'name': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'description': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'transform_protocol': { - 'allow_post': True, - 'allow_put': True, - 'default': 'esp', - 'validate': { - 'type:values': vpn_supported_transform_protocols}, - 'is_visible': True}, - 'auth_algorithm': { - 'allow_post': True, - 'allow_put': True, - 'default': 'sha1', - 'validate': { - 'type:values': vpn_supported_auth_algorithms - }, - 'is_visible': True}, - 'encryption_algorithm': { - 'allow_post': True, - 'allow_put': True, - 'default': 'aes-128', - 'validate': { - 'type:values': vpn_supported_encryption_algorithms - }, - 'is_visible': True}, - 'encapsulation_mode': { - 'allow_post': True, - 'allow_put': True, - 'default': 'tunnel', - 'validate': { - 'type:values': vpn_supported_encapsulation_mode - }, - 'is_visible': True}, - 'lifetime': {'allow_post': True, 'allow_put': True, - 'convert_to': attr.convert_none_to_empty_dict, - 'default': {}, - 'validate': { - 'type:dict_or_empty': { - 'units': { - 'type:values': vpn_supported_lifetime_units, - }, - 'value': { - 'type:range': vpn_lifetime_limits - }}}, - 'is_visible': True}, - 'pfs': {'allow_post': True, 'allow_put': True, - 'default': 'group5', - 'validate': {'type:values': vpn_supported_pfs}, - 'is_visible': True} - }, - - 'ikepolicies': { - 'id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True, - 'primary_key': True}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'required_by_policy': True, - 'is_visible': True}, - 'name': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'description': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'auth_algorithm': {'allow_post': True, 'allow_put': True, - 'default': 'sha1', - 'validate': { - 'type:values': vpn_supported_auth_algorithms}, - 'is_visible': True}, - 'encryption_algorithm': { - 'allow_post': True, 'allow_put': True, - 'default': 'aes-128', - 'validate': {'type:values': vpn_supported_encryption_algorithms}, - 'is_visible': True}, - 'phase1_negotiation_mode': { - 'allow_post': True, 'allow_put': True, - 'default': 'main', - 'validate': { - 'type:values': vpn_supported_phase1_negotiation_mode - }, - 'is_visible': True}, - 'lifetime': {'allow_post': True, 'allow_put': True, - 'convert_to': attr.convert_none_to_empty_dict, - 'default': {}, - 'validate': { - 'type:dict_or_empty': { - 'units': { - 'type:values': vpn_supported_lifetime_units, - }, - 'value': { - 'type:range': vpn_lifetime_limits, - }}}, - 'is_visible': True}, - 'ike_version': {'allow_post': True, 'allow_put': True, - 'default': 'v1', - 'validate': { - 'type:values': vpn_supported_ike_versions}, - 'is_visible': True}, - 'pfs': {'allow_post': True, 'allow_put': True, - 'default': 'group5', - 'validate': {'type:values': vpn_supported_pfs}, - 'is_visible': True} - } -} - - -class Vpnaas(extensions.ExtensionDescriptor): - - @classmethod - def get_name(cls): - return "VPN service" - - @classmethod - def get_alias(cls): - return "vpnaas" - - @classmethod - def get_description(cls): - return "Extension for VPN service" - - @classmethod - def get_namespace(cls): - return "https://wiki.openstack.org/Neutron/VPNaaS" - - @classmethod - def get_updated(cls): - return "2013-05-29T10:00:00-00:00" - - @classmethod - def get_resources(cls): - special_mappings = {'ikepolicies': 'ikepolicy', - 'ipsecpolicies': 'ipsecpolicy'} - plural_mappings = resource_helper.build_plural_mappings( - special_mappings, RESOURCE_ATTRIBUTE_MAP) - plural_mappings['peer_cidrs'] = 'peer_cidr' - attr.PLURALS.update(plural_mappings) - return resource_helper.build_resource_info(plural_mappings, - RESOURCE_ATTRIBUTE_MAP, - constants.VPN, - register_quota=True, - translate_name=True) - - @classmethod - def get_plugin_interface(cls): - return VPNPluginBase - - def update_attributes_map(self, attributes): - super(Vpnaas, self).update_attributes_map( - attributes, extension_attrs_map=RESOURCE_ATTRIBUTE_MAP) - - def get_extended_resources(self, version): - if version == "2.0": - return RESOURCE_ATTRIBUTE_MAP - else: - return {} - - -@six.add_metaclass(abc.ABCMeta) -class VPNPluginBase(service_base.ServicePluginBase): - - def get_plugin_name(self): - return constants.VPN - - def get_plugin_type(self): - return constants.VPN - - def get_plugin_description(self): - return 'VPN service plugin' - - @abc.abstractmethod - def get_vpnservices(self, context, filters=None, fields=None): - pass - - @abc.abstractmethod - def get_vpnservice(self, context, vpnservice_id, fields=None): - pass - - @abc.abstractmethod - def create_vpnservice(self, context, vpnservice): - pass - - @abc.abstractmethod - def update_vpnservice(self, context, vpnservice_id, vpnservice): - pass - - @abc.abstractmethod - def delete_vpnservice(self, context, vpnservice_id): - pass - - @abc.abstractmethod - def get_ipsec_site_connections(self, context, filters=None, fields=None): - pass - - @abc.abstractmethod - def get_ipsec_site_connection(self, context, - ipsecsite_conn_id, fields=None): - pass - - @abc.abstractmethod - def create_ipsec_site_connection(self, context, ipsec_site_connection): - pass - - @abc.abstractmethod - def update_ipsec_site_connection(self, context, - ipsecsite_conn_id, ipsec_site_connection): - pass - - @abc.abstractmethod - def delete_ipsec_site_connection(self, context, ipsecsite_conn_id): - pass - - @abc.abstractmethod - def get_ikepolicy(self, context, ikepolicy_id, fields=None): - pass - - @abc.abstractmethod - def get_ikepolicies(self, context, filters=None, fields=None): - pass - - @abc.abstractmethod - def create_ikepolicy(self, context, ikepolicy): - pass - - @abc.abstractmethod - def update_ikepolicy(self, context, ikepolicy_id, ikepolicy): - pass - - @abc.abstractmethod - def delete_ikepolicy(self, context, ikepolicy_id): - pass - - @abc.abstractmethod - def get_ipsecpolicies(self, context, filters=None, fields=None): - pass - - @abc.abstractmethod - def get_ipsecpolicy(self, context, ipsecpolicy_id, fields=None): - pass - - @abc.abstractmethod - def create_ipsecpolicy(self, context, ipsecpolicy): - pass - - @abc.abstractmethod - def update_ipsecpolicy(self, context, ipsecpolicy_id, ipsecpolicy): - pass - - @abc.abstractmethod - def delete_ipsecpolicy(self, context, ipsecpolicy_id): - pass