1 # Copyright (c) 2015 Openstack Foundation
3 # Licensed under the Apache License, Version 2.0 (the "License"); you may
4 # not use this file except in compliance with the License. You may obtain
5 # a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 # License for the specific language governing permissions and limitations
17 from oslo_utils import uuidutils
20 from neutron.common import constants as l3_constants
22 _uuid = uuidutils.generate_uuid
25 class FakeDev(object):
26 def __init__(self, name):
30 def get_ha_interface(ip='169.254.192.1', mac='12:34:56:78:2b:5d'):
32 return {'admin_state_up': True,
34 'device_owner': l3_constants.DEVICE_OWNER_ROUTER_HA_INTF,
35 'fixed_ips': [{'ip_address': ip,
37 'subnet_id': subnet_id}],
40 'name': u'L3 HA Admin port 0',
41 'network_id': _uuid(),
43 'subnets': [{'cidr': '169.254.192.0/18',
44 'gateway_ip': '169.254.255.254',
52 def prepare_router_data(ip_version=4, enable_snat=None, num_internal_ports=1,
53 enable_floating_ip=False, enable_ha=False,
54 extra_routes=False, dual_stack=False,
55 v6_ext_gw_with_sub=True, **kwargs):
58 gateway_mac = kwargs.get('gateway_mac', 'ca:fe:de:ad:be:ee')
60 for loop_version in (4, 6):
61 if loop_version == 4 and (ip_version == 4 or dual_stack):
62 ip_address = kwargs.get('ip_address', '19.4.4.4')
64 subnet_cidr = kwargs.get('subnet_cidr', '19.4.4.0/24')
65 gateway_ip = kwargs.get('gateway_ip', '19.4.4.1')
66 _extra_subnet = {'cidr': '9.4.5.0/24'}
67 elif (loop_version == 6 and (ip_version == 6 or dual_stack) and
69 ip_address = kwargs.get('ip_address', 'fd00::4')
71 subnet_cidr = kwargs.get('subnet_cidr', 'fd00::/64')
72 gateway_ip = kwargs.get('gateway_ip', 'fd00::1')
73 _extra_subnet = {'cidr': 'fd01::/64'}
77 fixed_ips.append({'ip_address': ip_address,
78 'subnet_id': subnet_id,
79 'prefixlen': prefixlen})
80 subnets.append({'id': subnet_id,
82 'gateway_ip': gateway_ip})
83 extra_subnets.append(_extra_subnet)
84 if not fixed_ips and v6_ext_gw_with_sub:
85 raise ValueError("Invalid ip_version: %s" % ip_version)
88 ex_gw_port = {'id': _uuid(),
89 'mac_address': gateway_mac,
90 'network_id': _uuid(),
91 'fixed_ips': fixed_ips,
93 'extra_subnets': extra_subnets}
97 routes = [{'destination': '8.8.8.0/24', 'nexthop': '19.4.4.4'}]
101 'distributed': False,
102 l3_constants.INTERFACE_KEY: [],
104 'gw_port': ex_gw_port}
106 if enable_floating_ip:
107 router[l3_constants.FLOATINGIP_KEY] = [{
111 'floating_ip_address': '19.4.4.2',
112 'fixed_ip_address': '10.0.0.1'}]
114 router_append_interface(router, count=num_internal_ports,
115 ip_version=ip_version, dual_stack=dual_stack)
118 router['ha_vr_id'] = 1
119 router[l3_constants.HA_INTERFACE_KEY] = (get_ha_interface())
121 if enable_snat is not None:
122 router['enable_snat'] = enable_snat
126 def get_subnet_id(port):
127 return port['fixed_ips'][0]['subnet_id']
130 def router_append_interface(router, count=1, ip_version=4, ra_mode=None,
131 addr_mode=None, dual_stack=False):
132 interfaces = router[l3_constants.INTERFACE_KEY]
134 [netaddr.IPNetwork(subnet['cidr']).version == ip_version
135 for p in interfaces for subnet in p['subnets']])
137 mac_address = netaddr.EUI('ca:fe:de:ad:be:ef')
138 mac_address.dialect = netaddr.mac_unix
139 for i in range(current, current + count):
142 for loop_version in (4, 6):
143 if loop_version == 4 and (ip_version == 4 or dual_stack):
144 ip_pool = '35.4.%i.4'
145 cidr_pool = '35.4.%i.0/24'
147 gw_pool = '35.4.%i.1'
148 elif loop_version == 6 and (ip_version == 6 or dual_stack):
149 ip_pool = 'fd01:%x:1::6'
150 cidr_pool = 'fd01:%x:1::/64'
152 gw_pool = 'fd01:%x:1::1'
156 fixed_ips.append({'ip_address': ip_pool % i,
157 'subnet_id': subnet_id,
158 'prefixlen': prefixlen})
159 subnets.append({'id': subnet_id,
160 'cidr': cidr_pool % i,
161 'gateway_ip': gw_pool % i,
162 'ipv6_ra_mode': ra_mode,
163 'ipv6_address_mode': addr_mode})
165 raise ValueError("Invalid ip_version: %s" % ip_version)
169 'network_id': _uuid(),
170 'admin_state_up': True,
171 'fixed_ips': fixed_ips,
172 'mac_address': str(mac_address),
174 mac_address.value += 1
177 def router_append_subnet(router, count=1, ip_version=4,
178 ipv6_subnet_modes=None, interface_id=None,
179 dns_nameservers=None):
181 subnet_mode_none = {'ra_mode': None, 'address_mode': None}
182 if not ipv6_subnet_modes:
183 ipv6_subnet_modes = [subnet_mode_none] * count
184 elif len(ipv6_subnet_modes) != count:
185 ipv6_subnet_modes.extend([subnet_mode_none for i in
186 moves.range(len(ipv6_subnet_modes),
190 ip_pool = '35.4.%i.4'
191 cidr_pool = '35.4.%i.0/24'
193 gw_pool = '35.4.%i.1'
194 elif ip_version == 6:
195 ip_pool = 'fd01:%x::6'
196 cidr_pool = 'fd01:%x::/64'
198 gw_pool = 'fd01:%x::1'
200 raise ValueError("Invalid ip_version: %s" % ip_version)
202 interfaces = copy.deepcopy(router.get(l3_constants.INTERFACE_KEY, []))
205 interface = next(i for i in interfaces
206 if i['id'] == interface_id)
207 except StopIteration:
208 raise ValueError("interface_id not found")
210 fixed_ips, subnets = interface['fixed_ips'], interface['subnets']
213 fixed_ips, subnets = [], []
215 num_existing_subnets = len(subnets)
216 for i in moves.range(count):
219 {'ip_address': ip_pool % (i + num_existing_subnets),
220 'subnet_id': subnet_id,
221 'prefixlen': prefixlen})
224 'cidr': cidr_pool % (i + num_existing_subnets),
225 'gateway_ip': gw_pool % (i + num_existing_subnets),
226 'dns_nameservers': dns_nameservers,
227 'ipv6_ra_mode': ipv6_subnet_modes[i]['ra_mode'],
228 'ipv6_address_mode': ipv6_subnet_modes[i]['address_mode']})
231 # Update old interface
232 index = interfaces.index(interface)
233 interfaces[index].update({'fixed_ips': fixed_ips, 'subnets': subnets})
235 # New interface appended to interfaces list
236 mac_address = netaddr.EUI('ca:fe:de:ad:be:ef')
237 mac_address.dialect = netaddr.mac_unix
240 'network_id': _uuid(),
241 'admin_state_up': True,
242 'mac_address': str(mac_address),
243 'fixed_ips': fixed_ips,
246 router[l3_constants.INTERFACE_KEY] = interfaces
249 def router_append_pd_enabled_subnet(router, count=1):
250 interfaces = router[l3_constants.INTERFACE_KEY]
251 current = sum(netaddr.IPNetwork(subnet['cidr']).version == 6
252 for p in interfaces for subnet in p['subnets'])
254 mac_address = netaddr.EUI('ca:fe:de:ad:be:ef')
255 mac_address.dialect = netaddr.mac_unix
257 for i in range(current, current + count):
259 intf = {'id': _uuid(),
260 'network_id': _uuid(),
261 'admin_state_up': True,
262 'fixed_ips': [{'ip_address': '::1',
264 'subnet_id': subnet_id}],
265 'mac_address': str(mac_address),
266 'subnets': [{'id': subnet_id,
267 'cidr': l3_constants.PROVISIONAL_IPV6_PD_PREFIX,
269 'ipv6_ra_mode': l3_constants.IPV6_SLAAC,
270 'subnetpool_id': l3_constants.IPV6_PD_POOL_ID}]}
271 interfaces.append(intf)
272 pd_intfs.append(intf)
273 mac_address.value += 1
277 def prepare_ext_gw_test(context, ri, dual_stack=False):
279 fixed_ips = [{'subnet_id': subnet_id,
280 'ip_address': '20.0.0.30',
282 subnets = [{'id': subnet_id,
283 'cidr': '20.0.0.0/24',
284 'gateway_ip': '20.0.0.1'}]
286 subnet_id_v6 = _uuid()
287 fixed_ips.append({'subnet_id': subnet_id_v6,
288 'ip_address': '2001:192:168:100::2',
290 subnets.append({'id': subnet_id_v6,
291 'cidr': '2001:192:168:100::/64',
292 'gateway_ip': '2001:192:168:100::1'})
293 ex_gw_port = {'fixed_ips': fixed_ips,
295 'extra_subnets': [{'cidr': '172.16.0.0/24'}],
297 'network_id': _uuid(),
298 'mac_address': 'ca:fe:de:ad:be:ef'}
299 interface_name = ri.get_external_device_name(ex_gw_port['id'])
301 context.device_exists.return_value = True
303 return interface_name, ex_gw_port