From 87a79256c494c36f2d9597313f430b24c0110161 Mon Sep 17 00:00:00 2001 From: Doug Wiegley Date: Fri, 15 Jan 2016 10:53:02 -0600 Subject: [PATCH] Start using neutron-lib for shared constants and exceptions Debtcollector warnings are enabled by an env var for now, to avoid blasting everyone's unit tests at once. Partially-Implements: blueprint neutron-lib Depends-On: I6991464acc3aef99f6ec5eff56a893deaaefe40b Change-Id: If183b7a6797834e29c377937fc06261aa3b00249 --- .pylintrc | 2 + neutron/common/_deprecate.py | 46 +++++ neutron/common/constants.py | 108 ++--------- neutron/common/exceptions.py | 364 ++++++++--------------------------- requirements.txt | 1 + 5 files changed, 152 insertions(+), 369 deletions(-) create mode 100644 neutron/common/_deprecate.py diff --git a/.pylintrc b/.pylintrc index 5037da9166c..65b52abe978 100644 --- a/.pylintrc +++ b/.pylintrc @@ -48,6 +48,8 @@ disable= unused-argument, unused-import, unused-variable, +# TODO(dougwig) - disable nonstandard-exception while we have neutron_lib shims + nonstandard-exception, # "C" Coding convention violations bad-continuation, invalid-name, diff --git a/neutron/common/_deprecate.py b/neutron/common/_deprecate.py new file mode 100644 index 00000000000..fd23aa5b471 --- /dev/null +++ b/neutron/common/_deprecate.py @@ -0,0 +1,46 @@ +# 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 copy +import debtcollector +import inspect +import os + + +class _DeprecateSubset(object): + def __init__(self, my_globals, other_mod): + self.other_mod = other_mod + self.my_globals = copy.copy(my_globals) + + def __getattr__(self, name): + a = self.my_globals.get(name) + if (not name.startswith("__") and not inspect.ismodule(a) and + name in vars(self.other_mod)): + + # These should be enabled after most have been cleaned up + # in neutron proper, which may not happen during the busy M-3. + + if os.getenv('NEUTRON_SHOW_DEPRECATION_WARNINGS'): + debtcollector.deprecate( + name, + message='moved to neutron_lib', + version='mitaka', + removal_version='newton', + stacklevel=4) + + return vars(self.other_mod)[name] + + try: + return self.my_globals[name] + except KeyError: + raise AttributeError() diff --git a/neutron/common/constants.py b/neutron/common/constants.py index 0272e9ab898..6bdc3eab624 100644 --- a/neutron/common/constants.py +++ b/neutron/common/constants.py @@ -13,53 +13,15 @@ # See the License for the specific language governing permissions and # limitations under the License. -# TODO(salv-orlando): Verify if a single set of operational -# status constants is achievable -NET_STATUS_ACTIVE = 'ACTIVE' -NET_STATUS_BUILD = 'BUILD' -NET_STATUS_DOWN = 'DOWN' -NET_STATUS_ERROR = 'ERROR' +import sys -PORT_STATUS_ACTIVE = 'ACTIVE' -PORT_STATUS_BUILD = 'BUILD' -PORT_STATUS_DOWN = 'DOWN' -PORT_STATUS_ERROR = 'ERROR' -PORT_STATUS_NOTAPPLICABLE = 'N/A' +from neutron_lib import constants as lib_constants -FLOATINGIP_STATUS_ACTIVE = 'ACTIVE' -FLOATINGIP_STATUS_DOWN = 'DOWN' -FLOATINGIP_STATUS_ERROR = 'ERROR' +from neutron.common import _deprecate -DEVICE_OWNER_COMPUTE_PREFIX = "compute:" -DEVICE_OWNER_NETWORK_PREFIX = "network:" -DEVICE_OWNER_NEUTRON_PREFIX = "neutron:" -DEVICE_OWNER_ROUTER_HA_INTF = (DEVICE_OWNER_NETWORK_PREFIX + - "router_ha_interface") -DEVICE_OWNER_ROUTER_INTF = DEVICE_OWNER_NETWORK_PREFIX + "router_interface" -DEVICE_OWNER_ROUTER_GW = DEVICE_OWNER_NETWORK_PREFIX + "router_gateway" -DEVICE_OWNER_FLOATINGIP = DEVICE_OWNER_NETWORK_PREFIX + "floatingip" -DEVICE_OWNER_DHCP = DEVICE_OWNER_NETWORK_PREFIX + "dhcp" -DEVICE_OWNER_DVR_INTERFACE = (DEVICE_OWNER_NETWORK_PREFIX + - "router_interface_distributed") -DEVICE_OWNER_AGENT_GW = (DEVICE_OWNER_NETWORK_PREFIX + - "floatingip_agent_gateway") -DEVICE_OWNER_ROUTER_SNAT = (DEVICE_OWNER_NETWORK_PREFIX + - "router_centralized_snat") -DEVICE_OWNER_LOADBALANCER = DEVICE_OWNER_NEUTRON_PREFIX + "LOADBALANCER" -DEVICE_OWNER_LOADBALANCERV2 = DEVICE_OWNER_NEUTRON_PREFIX + "LOADBALANCERV2" - -DEVICE_OWNER_PREFIXES = (DEVICE_OWNER_NETWORK_PREFIX, - DEVICE_OWNER_NEUTRON_PREFIX) - -# Collection used to identify devices owned by router interfaces. -# DEVICE_OWNER_ROUTER_HA_INTF is a special case and so is not included. -ROUTER_INTERFACE_OWNERS = (DEVICE_OWNER_ROUTER_INTF, - DEVICE_OWNER_DVR_INTERFACE) -ROUTER_INTERFACE_OWNERS_SNAT = (DEVICE_OWNER_ROUTER_INTF, - DEVICE_OWNER_DVR_INTERFACE, - DEVICE_OWNER_ROUTER_SNAT) -ROUTER_PORT_OWNERS = ROUTER_INTERFACE_OWNERS_SNAT + (DEVICE_OWNER_ROUTER_GW,) +ROUTER_PORT_OWNERS = lib_constants.ROUTER_INTERFACE_OWNERS_SNAT + \ + (lib_constants.DEVICE_OWNER_ROUTER_GW,) L3_AGENT_MODE_DVR = 'dvr' L3_AGENT_MODE_DVR_SNAT = 'dvr_snat' @@ -68,9 +30,6 @@ L3_AGENT_MODE = 'agent_mode' DEVICE_ID_RESERVED_DHCP_PORT = "reserved_dhcp_port" -FLOATINGIP_KEY = '_floatingips' -INTERFACE_KEY = '_interfaces' -HA_INTERFACE_KEY = '_ha_interface' HA_ROUTER_STATE_KEY = '_ha_state' METERING_LABEL_KEY = '_metering_labels' FLOATINGIP_AGENT_INTF_KEY = '_floatingip_agent_interfaces' @@ -83,47 +42,11 @@ MINIMUM_AGENTS_FOR_HA = 2 HA_ROUTER_STATE_ACTIVE = 'active' HA_ROUTER_STATE_STANDBY = 'standby' -IPv4 = 'IPv4' -IPv6 = 'IPv6' -IP_VERSION_4 = 4 -IP_VERSION_6 = 6 -IPv4_BITS = 32 -IPv6_BITS = 128 - -INVALID_MAC_ADDRESSES = ['00:00:00:00:00:00', 'FF:FF:FF:FF:FF:FF'] - -IPv4_ANY = '0.0.0.0/0' -IPv6_ANY = '::/0' -IP_ANY = {IP_VERSION_4: IPv4_ANY, IP_VERSION_6: IPv6_ANY} - -DHCP_RESPONSE_PORT = 68 - -FLOODING_ENTRY = ('00:00:00:00:00:00', '0.0.0.0') - -AGENT_TYPE_DHCP = 'DHCP agent' -AGENT_TYPE_OVS = 'Open vSwitch agent' -AGENT_TYPE_LINUXBRIDGE = 'Linux bridge agent' -AGENT_TYPE_OFA = 'OFA driver agent' -AGENT_TYPE_L3 = 'L3 agent' -AGENT_TYPE_LOADBALANCER = 'Loadbalancer agent' -AGENT_TYPE_METERING = 'Metering agent' -AGENT_TYPE_METADATA = 'Metadata agent' -AGENT_TYPE_NIC_SWITCH = 'NIC Switch agent' -L2_AGENT_TOPIC = 'N/A' - PAGINATION_INFINITE = 'infinite' SORT_DIRECTION_ASC = 'asc' SORT_DIRECTION_DESC = 'desc' -PORT_BINDING_EXT_ALIAS = 'binding' -L3_AGENT_SCHEDULER_EXT_ALIAS = 'l3_agent_scheduler' -DHCP_AGENT_SCHEDULER_EXT_ALIAS = 'dhcp_agent_scheduler' -LBAAS_AGENT_SCHEDULER_EXT_ALIAS = 'lbaas_agent_scheduler' -L3_DISTRIBUTED_EXT_ALIAS = 'dvr' -L3_HA_MODE_EXT_ALIAS = 'l3-ha' -SUBNET_ALLOCATION_EXT_ALIAS = 'subnet_allocation' - ETHERTYPE_IPV6 = 0x86DD # Protocol names and numbers for Security Groups/Firewalls @@ -225,8 +148,6 @@ DEVICE_NAME_MAX_LEN = 15 # vhost-user device names start with "vhu" VHOST_USER_DEVICE_PREFIX = 'vhu' -# Device names start with "tap" -TAP_DEVICE_PREFIX = 'tap' # The vswitch side of a veth pair for a nova iptables filter setup VETH_DEVICE_PREFIX = 'qvo' # prefix for SNAT interface in DVR @@ -235,7 +156,7 @@ SNAT_INT_DEV_PREFIX = 'sg-' # Possible prefixes to partial port IDs in interface names used by the OVS, # Linux Bridge, and IVS VIF drivers in Nova and the neutron agents. See the # 'get_ovs_interfaceid' method in Nova (nova/virt/libvirt/vif.py) for details. -INTERFACE_PREFIXES = (TAP_DEVICE_PREFIX, VETH_DEVICE_PREFIX, +INTERFACE_PREFIXES = (lib_constants.TAP_DEVICE_PREFIX, VETH_DEVICE_PREFIX, SNAT_INT_DEV_PREFIX) ATTRIBUTES_TO_UPDATE = 'attributes_to_update' @@ -268,9 +189,6 @@ IPV6_MIN_MTU = 1280 ROUTER_MARK_MASK = "0xffff" -# Time format -ISO8601_TIME_FORMAT = '%Y-%m-%dT%H:%M:%S.%f' - # Agent states as detected by server, used to reply on agent's state report # agent has just been registered AGENT_NEW = 'new' @@ -278,3 +196,17 @@ AGENT_NEW = 'new' AGENT_ALIVE = 'alive' # agent has just returned to alive after being dead AGENT_REVIVED = 'revived' + + +# Neutron-lib migration shim. This will wrap any constants that are moved +# to that library in a deprecation warning, until they can be updated to +# import directly from their new location. +# If you're wondering why we bother saving _OLD_REF, it is because if we +# do not, then the original module we are overwriting gets garbage collected, +# and then you will find some super strange behavior with inherited classes +# and the like. Saving a ref keeps it around. + +# WARNING: THESE MUST BE THE LAST TWO LINES IN THIS MODULE +_OLD_REF = sys.modules[__name__] +sys.modules[__name__] = _deprecate._DeprecateSubset(globals(), lib_constants) +# WARNING: THESE MUST BE THE LAST TWO LINES IN THIS MODULE diff --git a/neutron/common/exceptions.py b/neutron/common/exceptions.py index bbfbb2ff275..971eddb0c12 100644 --- a/neutron/common/exceptions.py +++ b/neutron/common/exceptions.py @@ -13,366 +13,165 @@ # License for the specific language governing permissions and limitations # under the License. -""" -Neutron base exception handling. -""" +import sys -from oslo_utils import excutils -import six +from neutron_lib import exceptions as e from neutron._i18n import _ +from neutron.common import _deprecate -class NeutronException(Exception): - """Base Neutron Exception. - - To correctly use this class, inherit from it and define - a 'message' property. That message will get printf'd - with the keyword arguments provided to the constructor. - """ - message = _("An unknown exception occurred.") - - def __init__(self, **kwargs): - try: - super(NeutronException, self).__init__(self.message % kwargs) - self.msg = self.message % kwargs - except Exception: - with excutils.save_and_reraise_exception() as ctxt: - if not self.use_fatal_exceptions(): - ctxt.reraise = False - # at least get the core message out if something happened - super(NeutronException, self).__init__(self.message) - - if six.PY2: - def __unicode__(self): - return unicode(self.msg) - - def __str__(self): - return self.msg - - def use_fatal_exceptions(self): - return False - - -class BadRequest(NeutronException): - message = _('Bad %(resource)s request: %(msg)s.') - - -class NotFound(NeutronException): - pass - - -class Conflict(NeutronException): - pass - - -class NotAuthorized(NeutronException): - message = _("Not authorized.") - - -class ServiceUnavailable(NeutronException): - message = _("The service is unavailable.") - - -class AdminRequired(NotAuthorized): - message = _("User does not have admin privileges: %(reason)s.") - - -class ObjectNotFound(NotFound): - message = _("Object %(id)s not found.") - - -class NetworkNotFound(NotFound): - message = _("Network %(net_id)s could not be found.") - - -class SubnetNotFound(NotFound): - message = _("Subnet %(subnet_id)s could not be found.") - - -class SubnetPoolNotFound(NotFound): +class SubnetPoolNotFound(e.NotFound): message = _("Subnet pool %(subnetpool_id)s could not be found.") -class PortNotFound(NotFound): - message = _("Port %(port_id)s could not be found.") - - -class QosPolicyNotFound(NotFound): +class QosPolicyNotFound(e.NotFound): message = _("QoS policy %(policy_id)s could not be found.") -class QosRuleNotFound(NotFound): +class QosRuleNotFound(e.NotFound): message = _("QoS rule %(rule_id)s for policy %(policy_id)s " "could not be found.") -class PortNotFoundOnNetwork(NotFound): - message = _("Port %(port_id)s could not be found " - "on network %(net_id)s.") - - -class PortQosBindingNotFound(NotFound): +class PortQosBindingNotFound(e.NotFound): message = _("QoS binding for port %(port_id)s and policy %(policy_id)s " "could not be found.") -class NetworkQosBindingNotFound(NotFound): +class NetworkQosBindingNotFound(e.NotFound): message = _("QoS binding for network %(net_id)s and policy %(policy_id)s " "could not be found.") -class PolicyFileNotFound(NotFound): +class PolicyFileNotFound(e.NotFound): message = _("Policy configuration policy.json could not be found.") -class PolicyInitError(NeutronException): +class PolicyInitError(e.NeutronException): message = _("Failed to init policy %(policy)s because %(reason)s.") -class PolicyCheckError(NeutronException): +class PolicyCheckError(e.NeutronException): message = _("Failed to check policy %(policy)s because %(reason)s.") -class StateInvalid(BadRequest): +class StateInvalid(e.BadRequest): message = _("Unsupported port state: %(port_state)s.") -class InUse(NeutronException): - message = _("The resource is in use.") - - -class QosPolicyInUse(InUse): +class QosPolicyInUse(e.InUse): message = _("QoS Policy %(policy_id)s is used by " "%(object_type)s %(object_id)s.") -class NetworkInUse(InUse): - message = _("Unable to complete operation on network %(net_id)s. " - "There are one or more ports still in use on the network.") - - -class SubnetInUse(InUse): - message = _("Unable to complete operation on subnet %(subnet_id)s " - "%(reason)s.") - - def __init__(self, **kwargs): - if 'reason' not in kwargs: - kwargs['reason'] = _("One or more ports have an IP allocation " - "from this subnet.") - super(SubnetInUse, self).__init__(**kwargs) - - -class SubnetPoolInUse(InUse): - message = _("Unable to complete operation on subnet pool " - "%(subnet_pool_id)s. %(reason)s.") - - def __init__(self, **kwargs): - if 'reason' not in kwargs: - kwargs['reason'] = _("Two or more concurrent subnets allocated.") - super(SubnetPoolInUse, self).__init__(**kwargs) - - -class PortInUse(InUse): - message = _("Unable to complete operation on port %(port_id)s " - "for network %(net_id)s. Port already has an attached " - "device %(device_id)s.") - - -class ServicePortInUse(InUse): - message = _("Port %(port_id)s cannot be deleted directly via the " - "port API: %(reason)s.") - - -class DhcpPortInUse(InUse): +class DhcpPortInUse(e.InUse): message = _("Port %(port_id)s is already acquired by another DHCP agent") -class PortBound(InUse): - message = _("Unable to complete operation on port %(port_id)s, " - "port is already bound, port type: %(vif_type)s, " - "old_mac %(old_mac)s, new_mac %(new_mac)s.") - - -class MacAddressInUse(InUse): - message = _("Unable to complete operation for network %(net_id)s. " - "The mac address %(mac)s is in use.") - - -class HostRoutesExhausted(BadRequest): +class HostRoutesExhausted(e.BadRequest): # NOTE(xchenum): probably make sense to use quota exceeded exception? message = _("Unable to complete operation for %(subnet_id)s. " "The number of host routes exceeds the limit %(quota)s.") -class DNSNameServersExhausted(BadRequest): +class DNSNameServersExhausted(e.BadRequest): # NOTE(xchenum): probably make sense to use quota exceeded exception? message = _("Unable to complete operation for %(subnet_id)s. " "The number of DNS nameservers exceeds the limit %(quota)s.") -class InvalidIpForNetwork(BadRequest): +class InvalidIpForNetwork(e.BadRequest): message = _("IP address %(ip_address)s is not a valid IP " "for any of the subnets on the specified network.") -class InvalidIpForSubnet(BadRequest): - message = _("IP address %(ip_address)s is not a valid IP " - "for the specified subnet.") - - -class IpAddressInUse(InUse): - message = _("Unable to complete operation for network %(net_id)s. " - "The IP address %(ip_address)s is in use.") - - -class VlanIdInUse(InUse): - message = _("Unable to create the network. " - "The VLAN %(vlan_id)s on physical network " - "%(physical_network)s is in use.") - - -class FlatNetworkInUse(InUse): +class FlatNetworkInUse(e.InUse): message = _("Unable to create the flat network. " "Physical network %(physical_network)s is in use.") -class TunnelIdInUse(InUse): - message = _("Unable to create the network. " - "The tunnel ID %(tunnel_id)s is in use.") - - -class TenantNetworksDisabled(ServiceUnavailable): +class TenantNetworksDisabled(e.ServiceUnavailable): message = _("Tenant network creation is not enabled.") -class ResourceExhausted(ServiceUnavailable): - pass - - -class NoNetworkAvailable(ResourceExhausted): - message = _("Unable to create the network. " - "No tenant network is available for allocation.") - - -class NoNetworkFoundInMaximumAllowedAttempts(ServiceUnavailable): +class NoNetworkFoundInMaximumAllowedAttempts(e.ServiceUnavailable): message = _("Unable to create the network. " "No available network found in maximum allowed attempts.") -class SubnetMismatchForPort(BadRequest): - message = _("Subnet on port %(port_id)s does not match " - "the requested subnet %(subnet_id)s.") - - -class MalformedRequestBody(BadRequest): +class MalformedRequestBody(e.BadRequest): message = _("Malformed request body: %(reason)s.") -class Invalid(NeutronException): - def __init__(self, message=None): - self.message = message - super(Invalid, self).__init__() - - -class InvalidInput(BadRequest): - message = _("Invalid input for operation: %(error_message)s.") - - -class InvalidAllocationPool(BadRequest): +class InvalidAllocationPool(e.BadRequest): message = _("The allocation pool %(pool)s is not valid.") -class UnsupportedPortDeviceOwner(Conflict): +class UnsupportedPortDeviceOwner(e.Conflict): message = _("Operation %(op)s is not supported for device_owner " "%(device_owner)s on port %(port_id)s.") -class OverlappingAllocationPools(Conflict): +class OverlappingAllocationPools(e.Conflict): message = _("Found overlapping allocation pools: " "%(pool_1)s %(pool_2)s for subnet %(subnet_cidr)s.") -class OutOfBoundsAllocationPool(BadRequest): +class OutOfBoundsAllocationPool(e.BadRequest): message = _("The allocation pool %(pool)s spans " "beyond the subnet cidr %(subnet_cidr)s.") -class MacAddressGenerationFailure(ServiceUnavailable): +class MacAddressGenerationFailure(e.ServiceUnavailable): message = _("Unable to generate unique mac on network %(net_id)s.") -class IpAddressGenerationFailure(Conflict): - message = _("No more IP addresses available on network %(net_id)s.") - - -class BridgeDoesNotExist(NeutronException): +class BridgeDoesNotExist(e.NeutronException): message = _("Bridge %(bridge)s does not exist.") -class PreexistingDeviceFailure(NeutronException): - message = _("Creation failed. %(dev_name)s already exists.") - - -class QuotaResourceUnknown(NotFound): +class QuotaResourceUnknown(e.NotFound): message = _("Unknown quota resources %(unknown)s.") -class OverQuota(Conflict): - message = _("Quota exceeded for resources: %(overs)s.") - - -class QuotaMissingTenant(BadRequest): +class QuotaMissingTenant(e.BadRequest): message = _("Tenant-id was missing from quota request.") -class InvalidQuotaValue(Conflict): +class InvalidQuotaValue(e.Conflict): message = _("Change would make usage less than 0 for the following " "resources: %(unders)s.") -class InvalidSharedSetting(Conflict): +class InvalidSharedSetting(e.Conflict): message = _("Unable to reconfigure sharing settings for network " "%(network)s. Multiple tenants are using it.") -class InvalidExtensionEnv(BadRequest): +class InvalidExtensionEnv(e.BadRequest): message = _("Invalid extension environment: %(reason)s.") -class ExtensionsNotFound(NotFound): +class ExtensionsNotFound(e.NotFound): message = _("Extensions not found: %(extensions)s.") -class InvalidContentType(NeutronException): +class InvalidContentType(e.NeutronException): message = _("Invalid content type %(content_type)s.") -class ExternalIpAddressExhausted(BadRequest): - message = _("Unable to find any IP address on external " - "network %(net_id)s.") - - -class TooManyExternalNetworks(NeutronException): - message = _("More than one external network exists.") - - -class InvalidConfigurationOption(NeutronException): - message = _("An invalid value was provided for %(opt_name)s: " - "%(opt_value)s.") - - -class GatewayConflictWithAllocationPools(InUse): +class GatewayConflictWithAllocationPools(e.InUse): message = _("Gateway ip %(ip_address)s conflicts with " "allocation pool %(pool)s.") -class GatewayIpInUse(InUse): +class GatewayIpInUse(e.InUse): message = _("Current gateway ip %(ip_address)s already in use " "by port %(port_id)s. Unable to update.") -class NetworkVlanRangeError(NeutronException): +class NetworkVlanRangeError(e.NeutronException): message = _("Invalid network VLAN range: '%(vlan_range)s' - '%(error)s'.") def __init__(self, **kwargs): @@ -382,47 +181,36 @@ class NetworkVlanRangeError(NeutronException): super(NetworkVlanRangeError, self).__init__(**kwargs) -class PhysicalNetworkNameError(NeutronException): +class PhysicalNetworkNameError(e.NeutronException): message = _("Empty physical network name.") -class NetworkTunnelRangeError(NeutronException): - message = _("Invalid network tunnel range: " - "'%(tunnel_range)s' - %(error)s.") - - def __init__(self, **kwargs): - # Convert tunnel_range tuple to 'start:end' format for display - if isinstance(kwargs['tunnel_range'], tuple): - kwargs['tunnel_range'] = "%d:%d" % kwargs['tunnel_range'] - super(NetworkTunnelRangeError, self).__init__(**kwargs) - - -class NetworkVxlanPortRangeError(NeutronException): +class NetworkVxlanPortRangeError(e.NeutronException): message = _("Invalid network VXLAN port range: '%(vxlan_range)s'.") -class VxlanNetworkUnsupported(NeutronException): +class VxlanNetworkUnsupported(e.NeutronException): message = _("VXLAN network unsupported.") -class DuplicatedExtension(NeutronException): +class DuplicatedExtension(e.NeutronException): message = _("Found duplicate extension: %(alias)s.") -class DeviceIDNotOwnedByTenant(Conflict): +class DeviceIDNotOwnedByTenant(e.Conflict): message = _("The following device_id %(device_id)s is not owned by your " "tenant or matches another tenants router.") -class InvalidCIDR(BadRequest): +class InvalidCIDR(e.BadRequest): message = _("Invalid CIDR %(input)s given as IP prefix.") -class RouterNotCompatibleWithAgent(NeutronException): +class RouterNotCompatibleWithAgent(e.NeutronException): message = _("Router '%(router_id)s' is not compatible with this agent.") -class DvrHaRouterNotSupported(NeutronException): +class DvrHaRouterNotSupported(e.NeutronException): message = _("Router '%(router_id)s' cannot be both DVR and HA.") @@ -431,31 +219,31 @@ class FailToDropPrivilegesExit(SystemExit): code = 99 -class FloatingIpSetupException(NeutronException): +class FloatingIpSetupException(e.NeutronException): def __init__(self, message=None): self.message = message super(FloatingIpSetupException, self).__init__() -class IpTablesApplyException(NeutronException): +class IpTablesApplyException(e.NeutronException): def __init__(self, message=None): self.message = message super(IpTablesApplyException, self).__init__() -class NetworkIdOrRouterIdRequiredError(NeutronException): +class NetworkIdOrRouterIdRequiredError(e.NeutronException): message = _('Both network_id and router_id are None. ' 'One must be provided.') -class AbortSyncRouters(NeutronException): +class AbortSyncRouters(e.NeutronException): message = _("Aborting periodic_sync_routers_task due to an error.") # Shared *aas exceptions, pending them being refactored out of Neutron # proper. -class FirewallInternalDriverError(NeutronException): +class FirewallInternalDriverError(e.NeutronException): """Fwaas exception for all driver errors. On any failure or exception in the driver, driver should log it and @@ -464,87 +252,101 @@ class FirewallInternalDriverError(NeutronException): message = _("%(driver)s: Internal driver error.") -class MissingMinSubnetPoolPrefix(BadRequest): +class MissingMinSubnetPoolPrefix(e.BadRequest): message = _("Unspecified minimum subnet pool prefix.") -class EmptySubnetPoolPrefixList(BadRequest): +class EmptySubnetPoolPrefixList(e.BadRequest): message = _("Empty subnet pool prefix list.") -class PrefixVersionMismatch(BadRequest): +class PrefixVersionMismatch(e.BadRequest): message = _("Cannot mix IPv4 and IPv6 prefixes in a subnet pool.") -class UnsupportedMinSubnetPoolPrefix(BadRequest): +class UnsupportedMinSubnetPoolPrefix(e.BadRequest): message = _("Prefix '%(prefix)s' not supported in IPv%(version)s pool.") -class IllegalSubnetPoolPrefixBounds(BadRequest): +class IllegalSubnetPoolPrefixBounds(e.BadRequest): message = _("Illegal prefix bounds: %(prefix_type)s=%(prefixlen)s, " "%(base_prefix_type)s=%(base_prefixlen)s.") -class IllegalSubnetPoolPrefixUpdate(BadRequest): +class IllegalSubnetPoolPrefixUpdate(e.BadRequest): message = _("Illegal update to prefixes: %(msg)s.") -class SubnetAllocationError(NeutronException): +class SubnetAllocationError(e.NeutronException): message = _("Failed to allocate subnet: %(reason)s.") -class AddressScopePrefixConflict(Conflict): +class AddressScopePrefixConflict(e.Conflict): message = _("Failed to associate address scope: subnetpools " "within an address scope must have unique prefixes.") -class IllegalSubnetPoolAssociationToAddressScope(BadRequest): +class IllegalSubnetPoolAssociationToAddressScope(e.BadRequest): message = _("Illegal subnetpool association: subnetpool %(subnetpool_id)s " "cannot be associated with address scope " "%(address_scope_id)s.") -class IllegalSubnetPoolIpVersionAssociationToAddressScope(BadRequest): +class IllegalSubnetPoolIpVersionAssociationToAddressScope(e.BadRequest): message = _("Illegal subnetpool association: subnetpool %(subnetpool_id)s " "cannot associate with address scope %(address_scope_id)s " "because subnetpool ip_version is not %(ip_version)s.") -class IllegalSubnetPoolUpdate(BadRequest): +class IllegalSubnetPoolUpdate(e.BadRequest): message = _("Illegal subnetpool update : %(reason)s.") -class MinPrefixSubnetAllocationError(BadRequest): +class MinPrefixSubnetAllocationError(e.BadRequest): message = _("Unable to allocate subnet with prefix length %(prefixlen)s, " "minimum allowed prefix is %(min_prefixlen)s.") -class MaxPrefixSubnetAllocationError(BadRequest): +class MaxPrefixSubnetAllocationError(e.BadRequest): message = _("Unable to allocate subnet with prefix length %(prefixlen)s, " "maximum allowed prefix is %(max_prefixlen)s.") -class SubnetPoolDeleteError(BadRequest): +class SubnetPoolDeleteError(e.BadRequest): message = _("Unable to delete subnet pool: %(reason)s.") -class SubnetPoolQuotaExceeded(OverQuota): +class SubnetPoolQuotaExceeded(e.OverQuota): message = _("Per-tenant subnet pool prefix quota exceeded.") -class DeviceNotFoundError(NeutronException): +class DeviceNotFoundError(e.NeutronException): message = _("Device '%(device_name)s' does not exist.") -class NetworkSubnetPoolAffinityError(BadRequest): +class NetworkSubnetPoolAffinityError(e.BadRequest): message = _("Subnets hosted on the same network must be allocated from " "the same subnet pool.") -class ObjectActionError(NeutronException): +class ObjectActionError(e.NeutronException): message = _('Object action %(action)s failed because: %(reason)s.') -class CTZoneExhaustedError(NeutronException): +class CTZoneExhaustedError(e.NeutronException): message = _("IPtables conntrack zones exhausted, iptables rules cannot " "be applied.") + + +# Neutron-lib migration shim. This will wrap any exceptionss that are moved +# to that library in a deprecation warning, until they can be updated to +# import directly from their new location. +# If you're wondering why we bother saving _OLD_REF, it is because if we +# do not, then the original module we are overwriting gets garbage collected, +# and then you will find some super strange behavior with inherited classes +# and the like. Saving a ref keeps it around. + +# WARNING: THESE MUST BE THE LAST TWO LINES IN THIS MODULE +_OLD_REF = sys.modules[__name__] +sys.modules[__name__] = _deprecate._DeprecateSubset(globals(), e) +# WARNING: THESE MUST BE THE LAST TWO LINES IN THIS MODULE diff --git a/requirements.txt b/requirements.txt index 1cbc411fc12..5d0086cc81c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,6 +16,7 @@ requests!=2.9.0,>=2.8.1 # Apache-2.0 Jinja2>=2.8 # BSD License (3 clause) keystonemiddleware!=4.1.0,>=4.0.0 # Apache-2.0 netaddr!=0.7.16,>=0.7.12 # BSD +neutron-lib>=0.0.1 # Apache-2.0 python-neutronclient>=2.6.0 # Apache-2.0 retrying!=1.3.0,>=1.2.3 # Apache-2.0 ryu!=3.29,>=3.23.2 # Apache-2.0