a81f2d67a28523f657d26372572ba3b108cd2c82
[openstack-build/neutron-build.git] / neutron / tests / common / l3_test_common.py
1 # Copyright (c) 2015 Openstack Foundation
2 #
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
6 #
7 #         http://www.apache.org/licenses/LICENSE-2.0
8 #
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
13 #    under the License.
14
15 import copy
16 import netaddr
17 from oslo_utils import uuidutils
18 from six import moves
19
20 from neutron.common import constants as l3_constants
21
22 _uuid = uuidutils.generate_uuid
23
24
25 class FakeDev(object):
26     def __init__(self, name):
27         self.name = name
28
29
30 def get_ha_interface(ip='169.254.192.1', mac='12:34:56:78:2b:5d'):
31     subnet_id = _uuid()
32     return {'admin_state_up': True,
33             'device_id': _uuid(),
34             'device_owner': l3_constants.DEVICE_OWNER_ROUTER_HA_INTF,
35             'fixed_ips': [{'ip_address': ip,
36                            'prefixlen': 18,
37                            'subnet_id': subnet_id}],
38             'id': _uuid(),
39             'mac_address': mac,
40             'name': u'L3 HA Admin port 0',
41             'network_id': _uuid(),
42             'status': u'ACTIVE',
43             'subnets': [{'cidr': '169.254.192.0/18',
44                          'gateway_ip': '169.254.255.254',
45                          'id': subnet_id}],
46             'tenant_id': '',
47             'agent_id': _uuid(),
48             'agent_host': 'aaa',
49             'priority': 1}
50
51
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):
56     fixed_ips = []
57     subnets = []
58     gateway_mac = kwargs.get('gateway_mac', 'ca:fe:de:ad:be:ee')
59     extra_subnets = []
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')
63             prefixlen = 24
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
68               v6_ext_gw_with_sub):
69             ip_address = kwargs.get('ip_address', 'fd00::4')
70             prefixlen = 64
71             subnet_cidr = kwargs.get('subnet_cidr', 'fd00::/64')
72             gateway_ip = kwargs.get('gateway_ip', 'fd00::1')
73             _extra_subnet = {'cidr': 'fd01::/64'}
74         else:
75             continue
76         subnet_id = _uuid()
77         fixed_ips.append({'ip_address': ip_address,
78                           'subnet_id': subnet_id,
79                           'prefixlen': prefixlen})
80         subnets.append({'id': subnet_id,
81                         'cidr': subnet_cidr,
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)
86
87     router_id = _uuid()
88     ex_gw_port = {'id': _uuid(),
89                   'mac_address': gateway_mac,
90                   'network_id': _uuid(),
91                   'fixed_ips': fixed_ips,
92                   'subnets': subnets,
93                   'extra_subnets': extra_subnets}
94
95     routes = []
96     if extra_routes:
97         routes = [{'destination': '8.8.8.0/24', 'nexthop': '19.4.4.4'}]
98
99     router = {
100         'id': router_id,
101         'distributed': False,
102         l3_constants.INTERFACE_KEY: [],
103         'routes': routes,
104         'gw_port': ex_gw_port}
105
106     if enable_floating_ip:
107         router[l3_constants.FLOATINGIP_KEY] = [{
108             'id': _uuid(),
109             'port_id': _uuid(),
110             'status': 'DOWN',
111             'floating_ip_address': '19.4.4.2',
112             'fixed_ip_address': '10.0.0.1'}]
113
114     router_append_interface(router, count=num_internal_ports,
115                             ip_version=ip_version, dual_stack=dual_stack)
116     if enable_ha:
117         router['ha'] = True
118         router['ha_vr_id'] = 1
119         router[l3_constants.HA_INTERFACE_KEY] = (get_ha_interface())
120
121     if enable_snat is not None:
122         router['enable_snat'] = enable_snat
123     return router
124
125
126 def get_subnet_id(port):
127     return port['fixed_ips'][0]['subnet_id']
128
129
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]
133     current = sum(
134         [netaddr.IPNetwork(subnet['cidr']).version == ip_version
135          for p in interfaces for subnet in p['subnets']])
136
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):
140         fixed_ips = []
141         subnets = []
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'
146                 prefixlen = 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'
151                 prefixlen = 64
152                 gw_pool = 'fd01:%x:1::1'
153             else:
154                 continue
155             subnet_id = _uuid()
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})
164         if not fixed_ips:
165             raise ValueError("Invalid ip_version: %s" % ip_version)
166
167         interfaces.append(
168             {'id': _uuid(),
169              'network_id': _uuid(),
170              'admin_state_up': True,
171              'fixed_ips': fixed_ips,
172              'mac_address': str(mac_address),
173              'subnets': subnets})
174         mac_address.value += 1
175
176
177 def router_append_subnet(router, count=1, ip_version=4,
178                          ipv6_subnet_modes=None, interface_id=None,
179                          dns_nameservers=None):
180     if ip_version == 6:
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),
187                                                   count)])
188
189     if ip_version == 4:
190         ip_pool = '35.4.%i.4'
191         cidr_pool = '35.4.%i.0/24'
192         prefixlen = 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'
197         prefixlen = 64
198         gw_pool = 'fd01:%x::1'
199     else:
200         raise ValueError("Invalid ip_version: %s" % ip_version)
201
202     interfaces = copy.deepcopy(router.get(l3_constants.INTERFACE_KEY, []))
203     if interface_id:
204         try:
205             interface = next(i for i in interfaces
206                          if i['id'] == interface_id)
207         except StopIteration:
208             raise ValueError("interface_id not found")
209
210         fixed_ips, subnets = interface['fixed_ips'], interface['subnets']
211     else:
212         interface = None
213         fixed_ips, subnets = [], []
214
215     num_existing_subnets = len(subnets)
216     for i in moves.range(count):
217         subnet_id = _uuid()
218         fixed_ips.append(
219                 {'ip_address': ip_pool % (i + num_existing_subnets),
220                  'subnet_id': subnet_id,
221                  'prefixlen': prefixlen})
222         subnets.append(
223                 {'id': subnet_id,
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']})
229
230     if interface:
231         # Update old interface
232         index = interfaces.index(interface)
233         interfaces[index].update({'fixed_ips': fixed_ips, 'subnets': subnets})
234     else:
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
238         interfaces.append(
239             {'id': _uuid(),
240              'network_id': _uuid(),
241              'admin_state_up': True,
242              'mac_address': str(mac_address),
243              'fixed_ips': fixed_ips,
244              'subnets': subnets})
245
246     router[l3_constants.INTERFACE_KEY] = interfaces
247
248
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'])
253
254     mac_address = netaddr.EUI('ca:fe:de:ad:be:ef')
255     mac_address.dialect = netaddr.mac_unix
256     pd_intfs = []
257     for i in range(current, current + count):
258         subnet_id = _uuid()
259         intf = {'id': _uuid(),
260                 'network_id': _uuid(),
261                 'admin_state_up': True,
262                 'fixed_ips': [{'ip_address': '::1',
263                                'prefixlen': 64,
264                                'subnet_id': subnet_id}],
265                 'mac_address': str(mac_address),
266                 'subnets': [{'id': subnet_id,
267                              'cidr': l3_constants.PROVISIONAL_IPV6_PD_PREFIX,
268                              'gateway_ip': '::1',
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
274     return pd_intfs
275
276
277 def prepare_ext_gw_test(context, ri, dual_stack=False):
278     subnet_id = _uuid()
279     fixed_ips = [{'subnet_id': subnet_id,
280                   'ip_address': '20.0.0.30',
281                   'prefixlen': 24}]
282     subnets = [{'id': subnet_id,
283                 'cidr': '20.0.0.0/24',
284                 'gateway_ip': '20.0.0.1'}]
285     if dual_stack:
286         subnet_id_v6 = _uuid()
287         fixed_ips.append({'subnet_id': subnet_id_v6,
288                           'ip_address': '2001:192:168:100::2',
289                           'prefixlen': 64})
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,
294                   'subnets': subnets,
295                   'extra_subnets': [{'cidr': '172.16.0.0/24'}],
296                   'id': _uuid(),
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'])
300
301     context.device_exists.return_value = True
302
303     return interface_name, ex_gw_port