def _create_and_allocate_ipam_subnet( self, cidr, allocation_pools=attributes.ATTR_NOT_SPECIFIED, ip_version=4, v6_auto_address=False, tenant_id=None): v6_address_mode = attributes.ATTR_NOT_SPECIFIED if v6_auto_address: # set ip version to 6 regardless of what's been passed to the # method ip_version = 6 v6_address_mode = constants.IPV6_SLAAC subnet = self._create_subnet( self.plugin, self.ctx, self.net_id, cidr, ip_version=ip_version, allocation_pools=allocation_pools, v6_address_mode=v6_address_mode) # Build netaddr.IPRanges from allocation pools since IPAM SubnetRequest # objects are strongly typed allocation_pool_ranges = [netaddr.IPRange( pool['start'], pool['end']) for pool in subnet['allocation_pools']] subnet_req = ipam.SpecificSubnetRequest( tenant_id, subnet['id'], cidr, gateway_ip=subnet['gateway_ip'], allocation_pools=allocation_pool_ranges) ipam_subnet = self.ipam_pool.allocate_subnet(subnet_req) ipam_subnet.associate_neutron_subnet(subnet['id']) return ipam_subnet, subnet
def test_associate_non_existing_neutron_subnet_fails(self): subnet_req = ipam.SpecificSubnetRequest( 'tenant_id', 'meh', '192.168.0.0/24') ipam_subnet = self.ipam_pool.allocate_subnet(subnet_req) self.assertRaises(n_exc.SubnetNotFound, ipam_subnet.associate_neutron_subnet, 'meh')
def _create_subnet_from_implicit_pool(self, context, subnet): s = subnet['subnet'] self._validate_subnet(context, s) tenant_id = self._get_tenant_id_for_create(context, s) id = s.get('id', uuidutils.generate_uuid()) detail = ipam.SpecificSubnetRequest(tenant_id, id, s['cidr']) with context.session.begin(subtransactions=True): network = self._get_network(context, s["network_id"]) self._validate_subnet_cidr(context, network, s['cidr']) subnet = self._save_subnet(context, network, self._make_subnet_args(context, network.shared, detail, s), s['dns_nameservers'], s['host_routes'], s['allocation_pools']) if hasattr(network, 'external') and network.external: self._update_router_gw_ports(context, network, subnet) return self._make_subnet_dict(subnet)
def test_subnet_request(self): request = ipam.SpecificSubnetRequest(self.tenant_id, self.subnet_id, '1.2.3.0/24', gateway_ip='1.2.3.1') self.assertEqual(24, request.prefixlen) self.assertEqual(netaddr.IPAddress('1.2.3.1'), request.gateway_ip) self.assertEqual(netaddr.IPNetwork('1.2.3.0/24'), request.subnet_cidr)
def _prepare_specific_subnet_request(self, cidr): subnet = self._create_subnet( self.plugin, self.ctx, self.net_id, cidr) subnet_req = ipam.SpecificSubnetRequest( self._tenant_id, subnet['id'], cidr, gateway_ip=subnet['gateway_ip']) return subnet, subnet_req
def test_insufficient_prefix_space_for_specific_allocation(self): sp = self._create_subnet_pool(self.plugin, self.ctx, 'test-sp', ['10.1.0.0/24'], 21, 4) sp = self.plugin._get_subnetpool(self.ctx, sp['id']) sa = subnet_alloc.SubnetAllocator(sp) req = ipam.SpecificSubnetRequest(self._tenant_id, uuidutils.generate_uuid(), '10.1.0.0/21') self.assertRaises(n_exc.SubnetAllocationError, sa.allocate_subnet, self.ctx.session, req)
def __init__(self, tenant_id, subnet_id, cidr, gateway_ip=None, allocation_pools=None): self._req = ipam.SpecificSubnetRequest(tenant_id, subnet_id, cidr, gateway_ip=gateway_ip, allocation_pools=None)
def test_subnetpool_default_quota_exceeded(self): sp = self._create_subnet_pool(self.plugin, self.ctx, 'test-sp', ['fe80::/48'], 48, 6, default_quota=1) sp = self.plugin._get_subnetpool(self.ctx, sp['id']) sa = subnet_alloc.SubnetAllocator(sp, self.ctx) req = ipam.SpecificSubnetRequest(self._tenant_id, uuidutils.generate_uuid(), 'fe80::/63') self.assertRaises(n_exc.SubnetPoolQuotaExceeded, sa.allocate_subnet, req)
def test_allocate_specific_subnet_specific_gateway(self): sp = self._create_subnet_pool(self.plugin, self.ctx, 'test-sp', ['10.1.0.0/16', '192.168.1.0/24'], 21, 4) sp = self.plugin._get_subnetpool(self.ctx, sp['id']) with self.ctx.session.begin(subtransactions=True): sa = subnet_alloc.SubnetAllocator(sp) req = ipam.SpecificSubnetRequest(self._tenant_id, uuidutils.generate_uuid(), '10.1.2.0/24', gateway_ip='10.1.2.254') res = sa.allocate_subnet(self.ctx.session, req) detail = res.get_details() self.assertEqual(detail.gateway_ip, netaddr.IPAddress('10.1.2.254'))
def test_allocate_specific_subnet(self): sp = self._create_subnet_pool(self.plugin, self.ctx, 'test-sp', ['10.1.0.0/16', '192.168.1.0/24'], 21, 4) with self.ctx.session.begin(subtransactions=True): sp = self.plugin._get_subnetpool(self.ctx, sp['id']) sa = subnet_alloc.SubnetAllocator(sp) req = ipam.SpecificSubnetRequest(self._tenant_id, uuidutils.generate_uuid(), '10.1.2.0/24') res = sa.allocate_subnet(self.ctx.session, req) detail = res.get_details() sp = self._get_subnetpool(self.ctx, self.plugin, sp['id']) self.assertEqual(str(detail.subnet.cidr), '10.1.2.0/24') self.assertEqual(detail.prefixlen, 24)
def _make_subnet_request(self, tenant_id, subnet, subnetpool): cidr = subnet.get('cidr') subnet_id = subnet.get('id', uuidutils.generate_uuid()) is_any_subnetpool_request = not attributes.is_attr_set(cidr) if is_any_subnetpool_request: prefixlen = subnet['prefixlen'] if not attributes.is_attr_set(prefixlen): prefixlen = int(subnetpool['default_prefixlen']) return ipam.AnySubnetRequest( tenant_id, subnet_id, utils.ip_version_from_int(subnetpool['ip_version']), prefixlen) else: return ipam.SpecificSubnetRequest(tenant_id, subnet_id, cidr)
def test_allocate_specific_ipv6_subnet_specific_gateway(self): # Same scenario as described in bug #1466322 sp = self._create_subnet_pool(self.plugin, self.ctx, 'test-sp', ['2210::/64'], 64, 6) sp = self.plugin._get_subnetpool(self.ctx, sp['id']) with self.ctx.session.begin(subtransactions=True): sa = subnet_alloc.SubnetAllocator(sp, self.ctx) req = ipam.SpecificSubnetRequest(self._tenant_id, uuidutils.generate_uuid(), '2210::/64', '2210::ffff:ffff:ffff:ffff') res = sa.allocate_subnet(req) detail = res.get_details() self.assertEqual(detail.gateway_ip, netaddr.IPAddress('2210::ffff:ffff:ffff:ffff'))
def test_allocate_ipam_subnet_no_neutron_subnet_id(self): cidr = '10.0.0.0/24' allocation_pools = [netaddr.IPRange('10.0.0.100', '10.0.0.150'), netaddr.IPRange('10.0.0.200', '10.0.0.250')] subnet_req = ipam.SpecificSubnetRequest( self._tenant_id, None, cidr, allocation_pools=allocation_pools, gateway_ip='10.0.0.101') ipam_subnet = self.ipam_pool.allocate_subnet(subnet_req) self._verify_ipam_subnet_details(ipam_subnet, cidr, self._tenant_id, '10.0.0.101', allocation_pools)
def test__allocate_specific_ip_out_of_range(self): cidr = '10.0.0.0/24' subnet = self._create_subnet( self.plugin, self.ctx, self.net_id, cidr) subnet_req = ipam.SpecificSubnetRequest( 'tenant_id', subnet, cidr, gateway_ip=subnet['gateway_ip']) ipam_subnet = self.ipam_pool.allocate_subnet(subnet_req) with self.ctx.session.begin(): ranges = ipam_subnet._allocate_specific_ip( self.ctx.session, '192.168.0.1') # In this case _allocate_specific_ips does not fail, but # simply does not update availability ranges at all self.assertEqual(1, len(ranges)) # 10.0.0.1 should be allocated for gateway ip ranges.sort(key=convert_firstip_to_ipaddress) self.assertEqual('10.0.0.2', ranges[0]['first_ip']) self.assertEqual('10.0.0.254', ranges[0]['last_ip'])
def test_update_subnet_pools(self): cidr = '10.0.0.0/24' subnet, subnet_req = self._prepare_specific_subnet_request(cidr) ipam_subnet = self.ipam_pool.allocate_subnet(subnet_req) ipam_subnet.associate_neutron_subnet(subnet['id']) allocation_pools = [netaddr.IPRange('10.0.0.100', '10.0.0.150'), netaddr.IPRange('10.0.0.200', '10.0.0.250')] update_subnet_req = ipam.SpecificSubnetRequest( self._tenant_id, subnet['id'], cidr, gateway_ip=subnet['gateway_ip'], allocation_pools=allocation_pools) ipam_subnet = self.ipam_pool.update_subnet(update_subnet_req) self._verify_ipam_subnet_details( ipam_subnet, cidr, self._tenant_id, subnet['gateway_ip'], allocation_pools)
def test_allocate_subnet_for_non_existent_subnet_pass(self): # This test should pass because neutron subnet is not checked # until associate neutron subnet step subnet_req = ipam.SpecificSubnetRequest( 'tenant_id', 'meh', '192.168.0.0/24') self.ipam_pool.allocate_subnet(subnet_req)
def _test_allocate_subnet(self, subnet_id): subnet_req = ipam.SpecificSubnetRequest( 'tenant_id', subnet_id, '192.168.0.0/24') return self.ipam_pool.allocate_subnet(subnet_req)
def get_details(self): """Return subnet data as a SpecificSubnetRequest""" return ipam.SpecificSubnetRequest(self._tenant_id, self.subnet_manager.neutron_id, self._cidr, self._gateway_ip, self._pools)