@@ -397,7 +397,7 @@ def _create_subnet(self, fmt, net_id, cidr,
397
397
data = {'subnet' : {'network_id' : net_id ,
398
398
'ip_version' : constants .IP_VERSION_4 ,
399
399
'tenant_id' : self ._tenant_id }}
400
- if cidr :
400
+ if cidr and cidr is not constants . ATTR_NOT_SPECIFIED :
401
401
data ['subnet' ]['cidr' ] = cidr
402
402
for arg in ('ip_version' , 'tenant_id' , 'subnetpool_id' , 'prefixlen' ,
403
403
'enable_dhcp' , 'allocation_pools' , 'segment_id' ,
@@ -774,7 +774,9 @@ def subnet(self, network=None,
774
774
set_context = False ):
775
775
if project_id :
776
776
tenant_id = project_id
777
- cidr = netaddr .IPNetwork (cidr ) if cidr else None
777
+ if (cidr is not None and
778
+ cidr != constants .ATTR_NOT_SPECIFIED ):
779
+ cidr = netaddr .IPNetwork (cidr )
778
780
if (gateway_ip is not None and
779
781
gateway_ip != constants .ATTR_NOT_SPECIFIED ):
780
782
gateway_ip = netaddr .IPAddress (gateway_ip )
@@ -947,7 +949,7 @@ def _validate_resource(self, resource, keys, res_name):
947
949
if (k == 'gateway_ip' and ipv6_zero_gateway and
948
950
keys [k ][- 3 :] == "::0" ):
949
951
self .assertEqual (keys [k ][:- 1 ], resource [res_name ][k ])
950
- else :
952
+ elif keys [ k ] != constants . ATTR_NOT_SPECIFIED :
951
953
self .assertEqual (keys [k ], resource [res_name ][k ])
952
954
953
955
@@ -3265,7 +3267,6 @@ class TestSubnetsV2(NeutronDbPluginV2TestCase):
3265
3267
3266
3268
def _test_create_subnet (self , network = None , expected = None , ** kwargs ):
3267
3269
keys = kwargs .copy ()
3268
- keys .setdefault ('cidr' , '10.0.0.0/24' )
3269
3270
keys .setdefault ('ip_version' , constants .IP_VERSION_4 )
3270
3271
keys .setdefault ('enable_dhcp' , True )
3271
3272
with self .subnet (network = network , ** keys ) as subnet :
@@ -4005,17 +4006,25 @@ def test_create_subnet_ipv6_gw_values(self):
4005
4006
@testtools .skipIf (tools .is_bsd (), 'bug/1484837' )
4006
4007
def test_create_subnet_ipv6_pd_gw_values (self ):
4007
4008
cidr = constants .PROVISIONAL_IPV6_PD_PREFIX
4009
+ subnetpool_id = constants .IPV6_PD_POOL_ID
4008
4010
# Gateway is last IP in IPv6 DHCPv6 Stateless subnet
4009
4011
gateway = '::ffff:ffff:ffff:ffff'
4010
4012
allocation_pools = [{'start' : '::1' ,
4011
4013
'end' : '::ffff:ffff:ffff:fffe' }]
4012
4014
expected = {'gateway_ip' : gateway ,
4013
4015
'cidr' : cidr ,
4014
4016
'allocation_pools' : allocation_pools }
4017
+ # We do not specify a CIDR in the API call for a PD subnet, as it
4018
+ # is unsupported. Instead we specify the subnetpool_id as
4019
+ # "prefix_delegation" which is what happens via OSC's
4020
+ # --use-prefix-delegation argument. But the expected result is a
4021
+ # subnet object with the "::/64" PD prefix. Same comment applies below.
4015
4022
self ._test_create_subnet (expected = expected , gateway_ip = gateway ,
4016
- cidr = cidr , ip_version = constants .IP_VERSION_6 ,
4023
+ cidr = constants .ATTR_NOT_SPECIFIED ,
4024
+ ip_version = constants .IP_VERSION_6 ,
4017
4025
ipv6_ra_mode = constants .DHCPV6_STATELESS ,
4018
- ipv6_address_mode = constants .DHCPV6_STATELESS )
4026
+ ipv6_address_mode = constants .DHCPV6_STATELESS ,
4027
+ subnetpool_id = subnetpool_id )
4019
4028
# Gateway is first IP in IPv6 DHCPv6 Stateless subnet
4020
4029
gateway = '::1'
4021
4030
allocation_pools = [{'start' : '::2' ,
@@ -4024,18 +4033,22 @@ def test_create_subnet_ipv6_pd_gw_values(self):
4024
4033
'cidr' : cidr ,
4025
4034
'allocation_pools' : allocation_pools }
4026
4035
self ._test_create_subnet (expected = expected , gateway_ip = gateway ,
4027
- cidr = cidr , ip_version = constants .IP_VERSION_6 ,
4036
+ cidr = constants .ATTR_NOT_SPECIFIED ,
4037
+ ip_version = constants .IP_VERSION_6 ,
4028
4038
ipv6_ra_mode = constants .DHCPV6_STATELESS ,
4029
- ipv6_address_mode = constants .DHCPV6_STATELESS )
4039
+ ipv6_address_mode = constants .DHCPV6_STATELESS ,
4040
+ subnetpool_id = subnetpool_id )
4030
4041
# If gateway_ip is not specified and the subnet is using prefix
4031
4042
# delegation, until the CIDR is assigned, this value should be first
4032
4043
# IP from the subnet
4033
4044
expected = {'gateway_ip' : str (netaddr .IPNetwork (cidr ).network ),
4034
4045
'cidr' : cidr }
4035
4046
self ._test_create_subnet (expected = expected ,
4036
- cidr = cidr , ip_version = constants .IP_VERSION_6 ,
4047
+ cidr = constants .ATTR_NOT_SPECIFIED ,
4048
+ ip_version = constants .IP_VERSION_6 ,
4037
4049
ipv6_ra_mode = constants .IPV6_SLAAC ,
4038
- ipv6_address_mode = constants .IPV6_SLAAC )
4050
+ ipv6_address_mode = constants .IPV6_SLAAC ,
4051
+ subnetpool_id = subnetpool_id )
4039
4052
4040
4053
def test_create_subnet_gw_outside_cidr_returns_201 (self ):
4041
4054
with self .network () as network :
@@ -4132,14 +4145,21 @@ def test_create_subnet_with_v6_allocation_pool(self):
4132
4145
allocation_pools = allocation_pools )
4133
4146
4134
4147
@testtools .skipIf (tools .is_bsd (), 'bug/1484837' )
4135
- def test_create_subnet_with_v6_pd_allocation_pool (self ):
4148
+ def test_create_subnet_with_v6_pd_allocation_pool_returns_400 (self ):
4136
4149
gateway_ip = '::1'
4137
4150
cidr = constants .PROVISIONAL_IPV6_PD_PREFIX
4138
4151
allocation_pools = [{'start' : '::2' ,
4139
4152
'end' : '::ffff:ffff:ffff:fffe' }]
4140
- self ._test_create_subnet (gateway_ip = gateway_ip ,
4141
- cidr = cidr , ip_version = constants .IP_VERSION_6 ,
4142
- allocation_pools = allocation_pools )
4153
+ # Creating a subnet object with the "::/64" PD prefix is invalid
4154
+ # unless the subnetpool_id is also passed as "prefix_delegation"
4155
+ with testlib_api .ExpectedException (
4156
+ webob .exc .HTTPClientError ) as ctx_manager :
4157
+ self ._test_create_subnet (gateway_ip = gateway_ip ,
4158
+ cidr = cidr ,
4159
+ ip_version = constants .IP_VERSION_6 ,
4160
+ allocation_pools = allocation_pools )
4161
+ self .assertEqual (webob .exc .HTTPClientError .code ,
4162
+ ctx_manager .exception .code )
4143
4163
4144
4164
def test_create_subnet_with_large_allocation_pool (self ):
4145
4165
gateway_ip = '10.0.0.1'
@@ -4350,10 +4370,10 @@ def _test_validate_subnet_ipv6_pd_modes(self, cur_subnet=None,
4350
4370
for mode , value in modes .items ():
4351
4371
new_subnet [mode ] = value
4352
4372
if expect_success :
4353
- plugin ._validate_subnet (ctx , new_subnet , cur_subnet )
4373
+ plugin ._validate_subnet (ctx , new_subnet , cur_subnet , True )
4354
4374
else :
4355
4375
self .assertRaises (lib_exc .InvalidInput , plugin ._validate_subnet ,
4356
- ctx , new_subnet , cur_subnet )
4376
+ ctx , new_subnet , cur_subnet , True )
4357
4377
4358
4378
def test_create_subnet_ipv6_ra_modes (self ):
4359
4379
# Test all RA modes with no address mode specified
0 commit comments