# Copyright (c) 2015 OpenStack Foundation # # 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 netaddr from neutron_lib import constants as l3_constants from oslo_utils import uuidutils from six import moves from neutron.common import constants as n_const _uuid = uuidutils.generate_uuid class FakeDev(object): def __init__(self, name): self.name = name def get_ha_interface(ip='169.254.192.1', mac='12:34:56:78:2b:5d'): subnet_id = _uuid() return {'admin_state_up': True, 'device_id': _uuid(), 'device_owner': l3_constants.DEVICE_OWNER_ROUTER_HA_INTF, 'fixed_ips': [{'ip_address': ip, 'prefixlen': 18, 'subnet_id': subnet_id}], 'id': _uuid(), 'mac_address': mac, 'name': u'L3 HA Admin port 0', 'network_id': _uuid(), 'status': u'ACTIVE', 'subnets': [{'cidr': '169.254.192.0/18', 'gateway_ip': '169.254.255.254', 'id': subnet_id}], 'tenant_id': '', 'agent_id': _uuid(), 'agent_host': 'aaa', 'priority': 1} def prepare_router_data(ip_version=4, enable_snat=None, num_internal_ports=1, enable_floating_ip=False, enable_ha=False, extra_routes=False, dual_stack=False, enable_gw=True, v6_ext_gw_with_sub=True, **kwargs): fixed_ips = [] subnets = [] gateway_mac = kwargs.get('gateway_mac', 'ca:fe:de:ad:be:ee') extra_subnets = [] for loop_version in (4, 6): if loop_version == 4 and (ip_version == 4 or dual_stack): ip_address = kwargs.get('ip_address', '19.4.4.4') prefixlen = 24 subnet_cidr = kwargs.get('subnet_cidr', '19.4.4.0/24') gateway_ip = kwargs.get('gateway_ip', '19.4.4.1') _extra_subnet = {'cidr': '9.4.5.0/24'} elif (loop_version == 6 and (ip_version == 6 or dual_stack) and v6_ext_gw_with_sub): ip_address = kwargs.get('ip_address', 'fd00::4') prefixlen = 64 subnet_cidr = kwargs.get('subnet_cidr', 'fd00::/64') gateway_ip = kwargs.get('gateway_ip', 'fd00::1') _extra_subnet = {'cidr': 'fd01::/64'} else: continue subnet_id = _uuid() fixed_ips.append({'ip_address': ip_address, 'subnet_id': subnet_id, 'prefixlen': prefixlen}) subnets.append({'id': subnet_id, 'cidr': subnet_cidr, 'gateway_ip': gateway_ip}) extra_subnets.append(_extra_subnet) if not fixed_ips and v6_ext_gw_with_sub: raise ValueError("Invalid ip_version: %s" % ip_version) router_id = _uuid() ex_gw_port = {} if enable_gw: ex_gw_port = {'id': _uuid(), 'mac_address': gateway_mac, 'network_id': _uuid(), 'fixed_ips': fixed_ips, 'subnets': subnets, 'extra_subnets': extra_subnets} routes = [] if extra_routes: routes = [{'destination': '8.8.8.0/24', 'nexthop': '19.4.4.4'}] router = { 'id': router_id, 'distributed': False, l3_constants.INTERFACE_KEY: [], 'routes': routes, 'gw_port': ex_gw_port} if enable_floating_ip: router[l3_constants.FLOATINGIP_KEY] = [{ 'id': _uuid(), 'port_id': _uuid(), 'status': 'DOWN', 'floating_ip_address': '19.4.4.2', 'fixed_ip_address': '10.0.0.1'}] router_append_interface(router, count=num_internal_ports, ip_version=ip_version, dual_stack=dual_stack) if enable_ha: router['ha'] = True router['ha_vr_id'] = 1 router[l3_constants.HA_INTERFACE_KEY] = (get_ha_interface()) if enable_snat is not None: router['enable_snat'] = enable_snat return router def get_subnet_id(port): return port['fixed_ips'][0]['subnet_id'] def router_append_interface(router, count=1, ip_version=4, ra_mode=None, addr_mode=None, dual_stack=False): interfaces = router[l3_constants.INTERFACE_KEY] current = sum( [netaddr.IPNetwork(subnet['cidr']).version == ip_version for p in interfaces for subnet in p['subnets']]) mac_address = netaddr.EUI('ca:fe:de:ad:be:ef') mac_address.dialect = netaddr.mac_unix for i in range(current, current + count): fixed_ips = [] subnets = [] for loop_version in (4, 6): if loop_version == 4 and (ip_version == 4 or dual_stack): ip_pool = '35.4.%i.4' cidr_pool = '35.4.%i.0/24' prefixlen = 24 gw_pool = '35.4.%i.1' elif loop_version == 6 and (ip_version == 6 or dual_stack): ip_pool = 'fd01:%x:1::6' cidr_pool = 'fd01:%x:1::/64' prefixlen = 64 gw_pool = 'fd01:%x:1::1' else: continue subnet_id = _uuid() fixed_ips.append({'ip_address': ip_pool % i, 'subnet_id': subnet_id, 'prefixlen': prefixlen}) subnets.append({'id': subnet_id, 'cidr': cidr_pool % i, 'gateway_ip': gw_pool % i, 'ipv6_ra_mode': ra_mode, 'ipv6_address_mode': addr_mode}) if not fixed_ips: raise ValueError("Invalid ip_version: %s" % ip_version) interfaces.append( {'id': _uuid(), 'network_id': _uuid(), 'admin_state_up': True, 'fixed_ips': fixed_ips, 'mac_address': str(mac_address), 'subnets': subnets}) mac_address.value += 1 def router_append_subnet(router, count=1, ip_version=4, ipv6_subnet_modes=None, interface_id=None, dns_nameservers=None, network_mtu=0): if ip_version == 6: subnet_mode_none = {'ra_mode': None, 'address_mode': None} if not ipv6_subnet_modes: ipv6_subnet_modes = [subnet_mode_none] * count elif len(ipv6_subnet_modes) != count: ipv6_subnet_modes.extend([subnet_mode_none for i in moves.range(len(ipv6_subnet_modes), count)]) if ip_version == 4: ip_pool = '35.4.%i.4' cidr_pool = '35.4.%i.0/24' prefixlen = 24 gw_pool = '35.4.%i.1' elif ip_version == 6: ip_pool = 'fd01:%x::6' cidr_pool = 'fd01:%x::/64' prefixlen = 64 gw_pool = 'fd01:%x::1' else: raise ValueError("Invalid ip_version: %s" % ip_version) interfaces = copy.deepcopy(router.get(l3_constants.INTERFACE_KEY, [])) if interface_id: try: interface = next(i for i in interfaces if i['id'] == interface_id) except StopIteration: raise ValueError("interface_id not found") fixed_ips, subnets = interface['fixed_ips'], interface['subnets'] else: interface = None fixed_ips, subnets = [], [] num_existing_subnets = len(subnets) for i in moves.range(count): subnet_id = _uuid() fixed_ips.append( {'ip_address': ip_pool % (i + num_existing_subnets), 'subnet_id': subnet_id, 'prefixlen': prefixlen}) subnets.append( {'id': subnet_id, 'cidr': cidr_pool % (i + num_existing_subnets), 'gateway_ip': gw_pool % (i + num_existing_subnets), 'dns_nameservers': dns_nameservers, 'ipv6_ra_mode': ipv6_subnet_modes[i]['ra_mode'], 'ipv6_address_mode': ipv6_subnet_modes[i]['address_mode']}) if interface: # Update old interface index = interfaces.index(interface) interfaces[index].update({'fixed_ips': fixed_ips, 'subnets': subnets}) else: # New interface appended to interfaces list mac_address = netaddr.EUI('ca:fe:de:ad:be:ef') mac_address.dialect = netaddr.mac_unix interfaces.append( {'id': _uuid(), 'mtu': network_mtu, 'network_id': _uuid(), 'admin_state_up': True, 'mac_address': str(mac_address), 'fixed_ips': fixed_ips, 'subnets': subnets}) router[l3_constants.INTERFACE_KEY] = interfaces def router_append_pd_enabled_subnet(router, count=1): interfaces = router[l3_constants.INTERFACE_KEY] current = sum(netaddr.IPNetwork(subnet['cidr']).version == 6 for p in interfaces for subnet in p['subnets']) mac_address = netaddr.EUI('ca:fe:de:ad:be:ef') mac_address.dialect = netaddr.mac_unix pd_intfs = [] for i in range(current, current + count): subnet_id = _uuid() intf = {'id': _uuid(), 'network_id': _uuid(), 'admin_state_up': True, 'fixed_ips': [{'ip_address': '::1', 'prefixlen': 64, 'subnet_id': subnet_id}], 'mac_address': str(mac_address), 'subnets': [{'id': subnet_id, 'cidr': n_const.PROVISIONAL_IPV6_PD_PREFIX, 'gateway_ip': '::1', 'ipv6_ra_mode': n_const.IPV6_SLAAC, 'subnetpool_id': l3_constants.IPV6_PD_POOL_ID}]} interfaces.append(intf) pd_intfs.append(intf) mac_address.value += 1 return pd_intfs def prepare_ext_gw_test(context, ri, dual_stack=False): subnet_id = _uuid() fixed_ips = [{'subnet_id': subnet_id, 'ip_address': '20.0.0.30', 'prefixlen': 24}] subnets = [{'id': subnet_id, 'cidr': '20.0.0.0/24', 'gateway_ip': '20.0.0.1'}] if dual_stack: subnet_id_v6 = _uuid() fixed_ips.append({'subnet_id': subnet_id_v6, 'ip_address': '2001:192:168:100::2', 'prefixlen': 64}) subnets.append({'id': subnet_id_v6, 'cidr': '2001:192:168:100::/64', 'gateway_ip': '2001:192:168:100::1'}) ex_gw_port = {'fixed_ips': fixed_ips, 'subnets': subnets, 'extra_subnets': [{'cidr': '172.16.0.0/24'}], 'id': _uuid(), 'network_id': _uuid(), 'mac_address': 'ca:fe:de:ad:be:ef'} interface_name = ri.get_external_device_name(ex_gw_port['id']) context.device_exists.return_value = True return interface_name, ex_gw_port