Introducing the Subnet OVO
This patch is introducing the following OVOs: - DNSNameServer - Route - IPAllocation - Subnet Partially-Implements: blueprint adopt-oslo-versioned-objects-for-db Change-Id: I3fca197098f24f68ea2b2915851c68dc170e781c
This commit is contained in:
parent
7327e8c210
commit
563fea3786
|
@ -0,0 +1,173 @@
|
|||
# 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 netaddr
|
||||
|
||||
from oslo_versionedobjects import base as obj_base
|
||||
from oslo_versionedobjects import fields as obj_fields
|
||||
|
||||
from neutron.db import models_v2
|
||||
from neutron.objects import base
|
||||
from neutron.objects import common_types
|
||||
|
||||
|
||||
@obj_base.VersionedObjectRegistry.register
|
||||
class DNSNameServer(base.NeutronDbObject):
|
||||
# Version 1.0: Initial version
|
||||
VERSION = '1.0'
|
||||
|
||||
db_model = models_v2.DNSNameServer
|
||||
|
||||
primary_keys = ['address', 'subnet_id']
|
||||
|
||||
foreign_keys = {'subnet_id': 'id'}
|
||||
|
||||
fields = {
|
||||
'address': obj_fields.StringField(),
|
||||
'subnet_id': obj_fields.UUIDField(),
|
||||
'order': obj_fields.IntegerField()
|
||||
}
|
||||
|
||||
|
||||
@obj_base.VersionedObjectRegistry.register
|
||||
class Route(base.NeutronDbObject):
|
||||
# Version 1.0: Initial version
|
||||
VERSION = '1.0'
|
||||
|
||||
db_model = models_v2.SubnetRoute
|
||||
|
||||
primary_keys = ['destination', 'nexthop', 'subnet_id']
|
||||
|
||||
foreign_keys = {'subnet_id': 'id'}
|
||||
|
||||
fields = {
|
||||
'subnet_id': obj_fields.UUIDField(),
|
||||
'destination': obj_fields.IPNetworkField(),
|
||||
'nexthop': obj_fields.IPAddressField()
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def modify_fields_from_db(cls, db_obj):
|
||||
# TODO(korzen) remove this method when IP and CIDR decorator ready
|
||||
result = super(Route, cls).modify_fields_from_db(db_obj)
|
||||
if 'destination' in result:
|
||||
result['destination'] = netaddr.IPNetwork(result['destination'])
|
||||
if 'nexthop' in result:
|
||||
result['nexthop'] = netaddr.IPAddress(result['nexthop'])
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def modify_fields_to_db(cls, fields):
|
||||
# TODO(korzen) remove this method when IP and CIDR decorator ready
|
||||
result = super(Route, cls).modify_fields_to_db(fields)
|
||||
if 'destination' in result:
|
||||
result['destination'] = str(result['destination'])
|
||||
if 'nexthop' in fields:
|
||||
result['nexthop'] = str(result['nexthop'])
|
||||
return result
|
||||
|
||||
|
||||
@obj_base.VersionedObjectRegistry.register
|
||||
class IPAllocationPool(base.NeutronDbObject):
|
||||
# Version 1.0: Initial version
|
||||
VERSION = '1.0'
|
||||
|
||||
db_model = models_v2.IPAllocationPool
|
||||
|
||||
foreign_keys = {'subnet_id': 'id'}
|
||||
|
||||
fields_need_translation = {
|
||||
'start': 'first_ip',
|
||||
'end': 'last_ip'
|
||||
}
|
||||
|
||||
fields = {
|
||||
'id': obj_fields.UUIDField(),
|
||||
'subnet_id': obj_fields.UUIDField(),
|
||||
'start': obj_fields.IPAddressField(),
|
||||
'end': obj_fields.IPAddressField()
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def modify_fields_from_db(cls, db_obj):
|
||||
# TODO(korzen) remove this method when IP and CIDR decorator ready
|
||||
result = super(IPAllocationPool, cls).modify_fields_from_db(db_obj)
|
||||
if 'start' in result:
|
||||
result['start'] = netaddr.IPAddress(result['start'])
|
||||
if 'end' in result:
|
||||
result['end'] = netaddr.IPAddress(result['end'])
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def modify_fields_to_db(cls, fields):
|
||||
# TODO(korzen) remove this method when IP and CIDR decorator ready
|
||||
result = super(IPAllocationPool, cls).modify_fields_to_db(fields)
|
||||
if 'first_ip' in result:
|
||||
result['first_ip'] = str(result['first_ip'])
|
||||
if 'last_ip' in result:
|
||||
result['last_ip'] = str(result['last_ip'])
|
||||
return result
|
||||
|
||||
|
||||
@obj_base.VersionedObjectRegistry.register
|
||||
class Subnet(base.NeutronDbObject):
|
||||
# Version 1.0: Initial version
|
||||
VERSION = '1.0'
|
||||
|
||||
db_model = models_v2.Subnet
|
||||
|
||||
fields = {
|
||||
'id': obj_fields.UUIDField(),
|
||||
'project_id': obj_fields.UUIDField(),
|
||||
'name': obj_fields.StringField(),
|
||||
'network_id': obj_fields.UUIDField(),
|
||||
'subnetpool_id': obj_fields.UUIDField(nullable=True),
|
||||
'ip_version': common_types.IPVersionEnumField(),
|
||||
'cidr': obj_fields.IPNetworkField(),
|
||||
'gateway_ip': obj_fields.IPAddressField(nullable=True),
|
||||
'allocation_pools': obj_fields.ListOfObjectsField('IPAllocationPool',
|
||||
nullable=True),
|
||||
'enable_dhcp': obj_fields.BooleanField(),
|
||||
'dns_nameservers': obj_fields.ListOfObjectsField('DNSNameServer',
|
||||
nullable=True),
|
||||
'host_routes': obj_fields.ListOfObjectsField('Route', nullable=True),
|
||||
'ipv6_ra_mode': common_types.IPV6ModeEnumField(nullable=True),
|
||||
'ipv6_address_mode': common_types.IPV6ModeEnumField(nullable=True)
|
||||
}
|
||||
|
||||
synthetic_fields = ['allocation_pools', 'dns_nameservers', 'host_routes']
|
||||
|
||||
foreign_keys = {'network_id': 'id'}
|
||||
|
||||
fields_need_translation = {
|
||||
'project_id': 'tenant_id'
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def modify_fields_from_db(cls, db_obj):
|
||||
# TODO(korzen) remove this method when IP and CIDR decorator ready
|
||||
result = super(Subnet, cls).modify_fields_from_db(db_obj)
|
||||
if 'cidr' in result:
|
||||
result['cidr'] = netaddr.IPNetwork(result['cidr'])
|
||||
if 'gateway_ip' in result and result['gateway_ip'] is not None:
|
||||
result['gateway_ip'] = netaddr.IPAddress(result['gateway_ip'])
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def modify_fields_to_db(cls, fields):
|
||||
# TODO(korzen) remove this method when IP and CIDR decorator ready
|
||||
result = super(Subnet, cls).modify_fields_to_db(fields)
|
||||
if 'cidr' in result:
|
||||
result['cidr'] = str(result['cidr'])
|
||||
if 'gateway_ip' in result and result['gateway_ip'] is not None:
|
||||
result['gateway_ip'] = str(result['gateway_ip'])
|
||||
return result
|
|
@ -300,3 +300,7 @@ def reset_random_seed():
|
|||
# at the same time get the same values from RNG
|
||||
seed = time.time() + os.getpid()
|
||||
random.seed(seed)
|
||||
|
||||
|
||||
def get_random_ipv6_mode():
|
||||
return random.choice(constants.IPV6_MODES)
|
||||
|
|
|
@ -30,6 +30,7 @@ from neutron.db import models_v2
|
|||
from neutron.objects import base
|
||||
from neutron.objects import common_types
|
||||
from neutron.objects.db import api as obj_db_api
|
||||
from neutron.objects import subnet
|
||||
from neutron.tests import base as test_base
|
||||
from neutron.tests import tools
|
||||
|
||||
|
@ -242,6 +243,7 @@ FIELD_TYPE_VALUE_GENERATOR_MAP = {
|
|||
obj_fields.DateTimeField: timeutils.utcnow,
|
||||
obj_fields.IPAddressField: tools.get_random_ip_address,
|
||||
common_types.MACAddressField: tools.get_random_EUI,
|
||||
common_types.IPV6ModeEnumField: tools.get_random_ipv6_mode,
|
||||
}
|
||||
|
||||
|
||||
|
@ -640,6 +642,21 @@ class BaseDbObjectTestCase(_BaseObjectTestCase):
|
|||
models_v2.Network,
|
||||
{'name': 'test-network1'})
|
||||
|
||||
def _create_test_subnet(self, network):
|
||||
test_subnet = {
|
||||
'tenant_id': uuidutils.generate_uuid(),
|
||||
'name': 'test-subnet1',
|
||||
'network_id': network['id'],
|
||||
'ip_version': 4,
|
||||
'cidr': '10.0.0.0/24',
|
||||
'gateway_ip': '10.0.0.1',
|
||||
'enable_dhcp': 1,
|
||||
'ipv6_ra_mode': None,
|
||||
'ipv6_address_mode': None
|
||||
}
|
||||
self._subnet = subnet.Subnet(self.context, **test_subnet)
|
||||
self._subnet.create()
|
||||
|
||||
def _create_test_port(self, network):
|
||||
# TODO(ihrachys): replace with port.create() once we get an object
|
||||
# implementation for ports
|
||||
|
|
|
@ -27,13 +27,17 @@ from neutron.tests import tools
|
|||
# corresponding version bump in the affected objects.
|
||||
object_data = {
|
||||
'AddressScope': '1.0-681cb915f973c92350fe2c797dec2ea4',
|
||||
'DNSNameServer': '1.0-bf87a85327e2d812d1666ede99d9918b',
|
||||
'ExtraDhcpOpt': '1.0-632f689cbeb36328995a7aed1d0a78d3',
|
||||
'IPAllocationPool': '1.0-371016a6480ed0b4299319cb46d9215d',
|
||||
'PortSecurity': '1.0-cf5b382a0112080ec4e0f23f697c7ab2',
|
||||
'AllowedAddressPair': '1.0-0d7380d7d4a32f72e6ae509af1476297',
|
||||
'QosBandwidthLimitRule': '1.1-4e44a8f5c2895ab1278399f87b40a13d',
|
||||
'QosDscpMarkingRule': '1.1-0313c6554b34fd10c753cb63d638256c',
|
||||
'QosRuleType': '1.1-8a53fef4c6a43839d477a85b787d22ce',
|
||||
'QosPolicy': '1.1-721fa60ea8f0e8f15d456d6e917dfe59',
|
||||
'Route': '1.0-a9883a63b416126f9e345523ec09483b',
|
||||
'Subnet': '1.0-12618b7d5dc7a69e2a05e9d6b15e9382',
|
||||
'SubnetPool': '1.0-320598830183ee739cbc9f32ebc26bba',
|
||||
'SubnetPoolPrefix': '1.0-13c15144135eb869faa4a76dc3ee3b6c',
|
||||
}
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import itertools
|
||||
|
||||
from neutron.objects import subnet
|
||||
from neutron.tests.unit.objects import test_base as obj_test_base
|
||||
from neutron.tests.unit import testlib_api
|
||||
|
||||
|
||||
class IPAllocationPoolObjectIfaceTestCase(
|
||||
obj_test_base.BaseObjectIfaceTestCase):
|
||||
|
||||
_test_class = subnet.IPAllocationPool
|
||||
|
||||
|
||||
class IPAllocationPoolDbObjectTestCase(obj_test_base.BaseDbObjectTestCase,
|
||||
testlib_api.SqlTestCase):
|
||||
|
||||
_test_class = subnet.IPAllocationPool
|
||||
|
||||
def setUp(self):
|
||||
super(IPAllocationPoolDbObjectTestCase, self).setUp()
|
||||
self._create_test_network()
|
||||
self._create_test_subnet(self._network)
|
||||
for obj in itertools.chain(self.db_objs, self.obj_fields):
|
||||
obj['subnet_id'] = self._subnet['id']
|
||||
|
||||
|
||||
class DNSNameServerObjectIfaceTestCase(obj_test_base.BaseObjectIfaceTestCase):
|
||||
|
||||
_test_class = subnet.DNSNameServer
|
||||
|
||||
|
||||
class DNSNameServerDbObjectTestCase(obj_test_base.BaseDbObjectTestCase,
|
||||
testlib_api.SqlTestCase):
|
||||
|
||||
_test_class = subnet.DNSNameServer
|
||||
|
||||
def setUp(self):
|
||||
super(DNSNameServerDbObjectTestCase, self).setUp()
|
||||
self._create_test_network()
|
||||
self._create_test_subnet(self._network)
|
||||
for obj in itertools.chain(self.db_objs, self.obj_fields):
|
||||
obj['subnet_id'] = self._subnet['id']
|
||||
|
||||
|
||||
class RouteObjectIfaceTestCase(obj_test_base.BaseObjectIfaceTestCase):
|
||||
|
||||
_test_class = subnet.Route
|
||||
|
||||
|
||||
class RouteDbObjectTestCase(obj_test_base.BaseDbObjectTestCase,
|
||||
testlib_api.SqlTestCase):
|
||||
|
||||
_test_class = subnet.Route
|
||||
|
||||
def setUp(self):
|
||||
super(RouteDbObjectTestCase, self).setUp()
|
||||
self._create_test_network()
|
||||
self._create_test_subnet(self._network)
|
||||
for obj in itertools.chain(self.db_objs, self.obj_fields):
|
||||
obj['subnet_id'] = self._subnet['id']
|
||||
|
||||
|
||||
class SubnetObjectIfaceTestCase(obj_test_base.BaseObjectIfaceTestCase):
|
||||
|
||||
_test_class = subnet.Subnet
|
||||
|
||||
|
||||
class SubnetDbObjectTestCase(obj_test_base.BaseDbObjectTestCase,
|
||||
testlib_api.SqlTestCase):
|
||||
|
||||
_test_class = subnet.Subnet
|
||||
|
||||
def setUp(self):
|
||||
super(SubnetDbObjectTestCase, self).setUp()
|
||||
self._create_test_network()
|
||||
for obj in itertools.chain(self.db_objs, self.obj_fields):
|
||||
obj['network_id'] = self._network['id']
|
Loading…
Reference in New Issue