diff options
-rw-r--r-- | nova/exception.py | 56 | ||||
-rw-r--r-- | nova/network/manager.py | 56 | ||||
-rw-r--r-- | nova/tests/network/test_manager.py | 22 |
3 files changed, 92 insertions, 42 deletions
diff --git a/nova/exception.py b/nova/exception.py index 53281a4be9..d3677ac9af 100644 --- a/nova/exception.py +++ b/nova/exception.py @@ -316,10 +316,6 @@ class InvalidContentType(Invalid): msg_fmt = _("Invalid content type %(content_type)s.") -class InvalidCidr(Invalid): - msg_fmt = _("Invalid cidr %(cidr)s.") - - class InvalidUnicodeParameter(Invalid): msg_fmt = _("Invalid Parameter: " "Unicode is not supported by the current database.") @@ -594,10 +590,51 @@ class NetworkInUse(NovaException): msg_fmt = _("Network %(network_id)s is still in use.") -class NetworkNotCreated(NovaException): +class InvalidNetworkParam(Invalid): + # NOTE(vish) base class for network create param errors + code = 422 + + +class NetworkNotCreated(InvalidNetworkParam): msg_fmt = _("%(req)s is required to create a network.") +class LabelTooLong(InvalidNetworkParam): + msg_fmt = _("Maximum allowed length for 'label' is 255.") + + +class InvalidIntValue(InvalidNetworkParam): + msg_fmt = _("%(key)s must be an integer.") + + +class InvalidCidr(InvalidNetworkParam): + msg_fmt = _("%(cidr)s is not a valid ip network.") + + +class InvalidAddress(InvalidNetworkParam): + msg_fmt = _("%(address)s is not a valid ip address.") + + +class AddressOutOfRange(InvalidNetworkParam): + msg_fmt = _("%(address)s is not within %(cidr)s.") + + +class DuplicateVlan(NovaException): + msg_fmt = _("Detected existing vlan with id %(vlan)d") + code = 409 + + +class CidrConflict(NovaException): + msg_fmt = _('Requested cidr (%(cidr)s) conflicts ' + 'with existing cidr (%(other)s)') + code = 409 + + +class NetworkHasProject(NetworkInUse): + msg_fmt = _('Network must be disassociated from project ' + '%(project_id)s before it can be deleted.') + + class NetworkNotFound(NotFound): msg_fmt = _("Network %(network_id)s could not be found.") @@ -1235,15 +1272,6 @@ class InstancePasswordSetFailed(NovaException): safe = True -class DuplicateVlan(NovaException): - msg_fmt = _("Detected existing vlan with id %(vlan)d") - - -class CidrConflict(NovaException): - msg_fmt = _("There was a conflict when trying to complete your request.") - code = 409 - - class InstanceNotFound(NotFound): ec2_code = 'InvalidInstanceID.NotFound' msg_fmt = _("Instance %(instance_id)s could not be found.") diff --git a/nova/network/manager.py b/nova/network/manager.py index 10b7158cb7..857a22a415 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -1072,7 +1072,7 @@ class NetworkManager(manager.Manager): continue kwargs[key] = int(value) except ValueError: - raise ValueError(_("%s must be an integer") % key) + raise exception.InvalidIntValue(key=key) def create_networks(self, context, label, cidr=None, multi_host=None, num_networks=None, @@ -1105,7 +1105,7 @@ class NetworkManager(manager.Manager): # Size of "label" column in nova.networks is 255, hence the restriction if len(label) > 255: - raise ValueError(_("Maximum allowed length for 'label' is 255.")) + raise exception.LabelTooLong() if not (kwargs["cidr"] or kwargs["cidr_v6"]): raise exception.NetworkNotCreated(req="cidr or cidr_v6") @@ -1118,10 +1118,22 @@ class NetworkManager(manager.Manager): if not kwargs[fld]: raise exception.NetworkNotCreated(req=fld) + if kwargs["cidr_v6"]: + # NOTE(vish): just for validation + try: + netaddr.IPNetwork(kwargs["cidr_v6"]) + except netaddr.AddrFormatError: + raise exception.InvalidCidr(cidr=kwargs["cidr_v6"]) + + if kwargs["cidr"]: + try: + fixnet = netaddr.IPNetwork(kwargs["cidr"]) + except netaddr.AddrFormatError: + raise exception.InvalidCidr(cidr=kwargs["cidr"]) + kwargs["num_networks"] = kwargs["num_networks"] or CONF.num_networks if not kwargs["network_size"]: if kwargs["cidr"]: - fixnet = netaddr.IPNetwork(kwargs["cidr"]) each_subnet_size = fixnet.size / kwargs["num_networks"] if each_subnet_size > CONF.network_size: subnet = 32 - int(math.log(CONF.network_size, 2)) @@ -1145,7 +1157,10 @@ class NetworkManager(manager.Manager): kwargs["dns1"] = kwargs["dns1"] or CONF.flat_network_dns if kwargs["fixed_cidr"]: - kwargs["fixed_cidr"] = netaddr.IPNetwork(kwargs["fixed_cidr"]) + try: + kwargs["fixed_cidr"] = netaddr.IPNetwork(kwargs["fixed_cidr"]) + except netaddr.AddrFormatError: + raise exception.InvalidCidr(cidr=kwargs["fixed_cidr"]) LOG.debug('Create network: |%s|', kwargs) return self._do_create_networks(context, **kwargs) @@ -1155,10 +1170,10 @@ class NetworkManager(manager.Manager): try: start = netaddr.IPAddress(ip) except netaddr.AddrFormatError: - raise ValueError(_("Not a valid IP Address")) + raise exception.InvalidAddress(address=ip) index = start.value - subnet.value if index < 0 or index >= subnet.size: - raise ValueError(_("IP not within cidr range")) + raise exception.AddressOutOfRange(address=ip, cidr=str(subnet)) return index def _do_create_networks(self, context, @@ -1222,13 +1237,12 @@ class NetworkManager(manager.Manager): subnets_v4.append(next_subnet) subnet = next_subnet else: - raise exception.CidrConflict(_('cidr already in use')) + raise exception.CidrConflict(cidr=subnet, + other=subnet) for used_subnet in used_subnets: if subnet in used_subnet: - msg = _('requested cidr (%(cidr)s) conflicts with ' - 'existing supernet (%(super)s)') - raise exception.CidrConflict( - msg % {'cidr': subnet, 'super': used_subnet}) + raise exception.CidrConflict(cidr=subnet, + other=used_subnet) if used_subnet in subnet: next_subnet = find_next(subnet) if next_subnet: @@ -1236,11 +1250,8 @@ class NetworkManager(manager.Manager): subnets_v4.append(next_subnet) subnet = next_subnet else: - msg = _('requested cidr (%(cidr)s) conflicts ' - 'with existing smaller cidr ' - '(%(smaller)s)') - raise exception.CidrConflict( - msg % {'cidr': subnet, 'smaller': used_subnet}) + raise exception.CidrConflict(cidr=subnet, + other=used_subnet) networks = objects.NetworkList(context=context, objects=[]) subnets = itertools.izip_longest(subnets_v4, subnets_v6) @@ -1269,17 +1280,11 @@ class NetworkManager(manager.Manager): if cidr and subnet_v4: current = subnet_v4[1] if allowed_start: - try: - val = self._index_of(subnet_v4, allowed_start) - except ValueError as exc: - raise ValueError('allowed_start: %s' % unicode(exc)) + val = self._index_of(subnet_v4, allowed_start) current = netaddr.IPAddress(allowed_start) bottom_reserved = val if allowed_end: - try: - val = self._index_of(subnet_v4, allowed_end) - except ValueError as exc: - raise ValueError('allowed_end: %s' % unicode(exc)) + val = self._index_of(subnet_v4, allowed_end) top_reserved = subnet_v4.size - 1 - val net.cidr = str(subnet_v4) net.netmask = str(subnet_v4.netmask) @@ -1353,8 +1358,7 @@ class NetworkManager(manager.Manager): LOG.debug('Delete network %s', network['uuid']) if require_disassociated and network.project_id is not None: - raise ValueError(_('Network must be disassociated from project %s' - ' before delete') % network.project_id) + raise exception.NetworkHasProject(project_id=network.project_id) network.destroy() @property diff --git a/nova/tests/network/test_manager.py b/nova/tests/network/test_manager.py index 61f8d67afc..22237bed7f 100644 --- a/nova/tests/network/test_manager.py +++ b/nova/tests/network/test_manager.py @@ -361,17 +361,35 @@ class FlatNetworkTestCase(test.TestCase): def test_validate_reserved_start_out_of_range(self): context_admin = context.RequestContext('testuser', 'testproject', is_admin=True) - self.assertRaises(ValueError, self.network.create_networks, + self.assertRaises(exception.AddressOutOfRange, + self.network.create_networks, context_admin, 'fake', '192.168.0.0/24', False, 1, 256, allowed_start='192.168.1.10') def test_validate_reserved_end_invalid(self): context_admin = context.RequestContext('testuser', 'testproject', is_admin=True) - self.assertRaises(ValueError, self.network.create_networks, + self.assertRaises(exception.InvalidAddress, + self.network.create_networks, context_admin, 'fake', '192.168.0.0/24', False, 1, 256, allowed_end='invalid') + def test_validate_cidr_invalid(self): + context_admin = context.RequestContext('testuser', 'testproject', + is_admin=True) + self.assertRaises(exception.InvalidCidr, + self.network.create_networks, + context_admin, 'fake', 'invalid', False, + 1, 256) + + def test_validate_non_int_size(self): + context_admin = context.RequestContext('testuser', 'testproject', + is_admin=True) + self.assertRaises(exception.InvalidIntValue, + self.network.create_networks, + context_admin, 'fake', '192.168.0.0/24', False, + 1, 'invalid') + def test_validate_networks_none_requested_networks(self): self.network.validate_networks(self.context, None) |