neutron/neutron/tests/unit/extensions/test_floating_ip_port_forwarding.py
Pedro Martins b271c82d10 Extend database to support portforwardings with port range
This patch is the second of a series of patches
to implement floating ip port forwarding with
port ranges.

The specification is defined in:
https://github.com/openstack/neutron-specs/blob/master/specs/wallaby/port-forwarding-port-ranges.rst

Implements: blueprint floatingips-portforwarding-ranges
Related-Bug: #1885921
Change-Id: I43e0b669096df865f37c74ddbd050b3b177fd5e5
2022-03-15 09:10:23 -03:00

286 lines
12 KiB
Python

#
# 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.
#
from unittest import mock
from neutron_lib import context
from oslo_utils import uuidutils
from webob import exc
from neutron.tests.unit.api import test_extensions
from neutron.tests.unit.extensions import \
test_expose_port_forwarding_in_fip as test_fip_pf
from neutron.tests.unit.extensions import test_l3
_uuid = uuidutils.generate_uuid
class FloatingIPPorForwardingTestCase(test_l3.L3BaseForIntTests,
test_l3.L3NatTestCaseMixin):
fmt = 'json'
def setUp(self):
mock.patch('neutron.api.rpc.handlers.resources_rpc.'
'ResourcesPushRpcApi').start()
svc_plugins = (test_fip_pf.PF_PLUGIN_NAME, test_fip_pf.L3_PLUGIN,
'neutron.services.qos.qos_plugin.QoSPlugin')
ext_mgr = test_fip_pf.ExtendFipPortForwardingExtensionManager()
super(FloatingIPPorForwardingTestCase, self).setUp(
ext_mgr=ext_mgr, service_plugins=svc_plugins)
self.ext_api = test_extensions.setup_extensions_middleware(ext_mgr)
def _create_fip_port_forwarding(self, fmt,
floating_ip_id,
external_port,
internal_port,
protocol,
internal_ip_address,
internal_port_id,
tenant_id=None,
description=None,
external_port_range=None,
internal_port_range=None):
tenant_id = tenant_id or _uuid()
data = {'port_forwarding': {
"protocol": protocol,
"internal_ip_address": internal_ip_address,
"internal_port_id": internal_port_id}
}
if external_port_range and internal_port_range:
data['port_forwarding'][
'internal_port_range'] = internal_port_range
data['port_forwarding'][
'external_port_range'] = external_port_range
else:
data['port_forwarding']['internal_port'] = internal_port
data['port_forwarding']['external_port'] = external_port
if description:
data['port_forwarding']['description'] = description
fip_pf_req = self._req(
'POST', 'floatingips', data,
fmt or self.fmt, id=floating_ip_id,
subresource='port_forwardings')
fip_pf_req.environ['neutron.context'] = context.Context(
'', tenant_id, is_admin=True)
return fip_pf_req.get_response(self.ext_api)
def _update_fip_port_forwarding(self, fmt, floating_ip_id,
port_forwarding_id, **kwargs):
port_forwarding = {}
for k, v in kwargs.items():
port_forwarding[k] = v
data = {'port_forwarding': port_forwarding}
fip_pf_req = self._req(
'PUT', 'floatingips', data,
fmt or self.fmt, id=floating_ip_id,
sub_id=port_forwarding_id,
subresource='port_forwardings')
return fip_pf_req.get_response(self.ext_api)
def test_create_floatingip_port_forwarding_with_port_number_0(self):
with self.network() as ext_net:
network_id = ext_net['network']['id']
self._set_net_external(network_id)
with self.subnet(ext_net, cidr='10.10.10.0/24'), \
self.router() as router, \
self.subnet(cidr='11.0.0.0/24') as private_subnet, \
self.port(private_subnet) as port:
self._add_external_gateway_to_router(
router['router']['id'],
network_id)
self._router_interface_action(
'add', router['router']['id'],
private_subnet['subnet']['id'],
None)
fip = self._make_floatingip(
self.fmt,
network_id)
self.assertIsNone(fip['floatingip'].get('port_id'))
res = self._create_fip_port_forwarding(
self.fmt, fip['floatingip']['id'],
2222, 0,
'tcp',
port['port']['fixed_ips'][0]['ip_address'],
port['port']['id'])
self.assertEqual(exc.HTTPBadRequest.code, res.status_int)
res = self._create_fip_port_forwarding(
self.fmt, fip['floatingip']['id'],
0, 22,
'tcp',
port['port']['fixed_ips'][0]['ip_address'],
port['port']['id'])
self.assertEqual(exc.HTTPBadRequest.code, res.status_int)
def test_create_floatingip_port_forwarding_with_description(self):
with self.network() as ext_net:
network_id = ext_net['network']['id']
self._set_net_external(network_id)
with self.subnet(ext_net, cidr='10.10.10.0/24'), \
self.router() as router, \
self.subnet(cidr='11.0.0.0/24') as private_subnet, \
self.port(private_subnet) as port:
self._add_external_gateway_to_router(
router['router']['id'],
network_id)
self._router_interface_action(
'add', router['router']['id'],
private_subnet['subnet']['id'],
None)
fip = self._make_floatingip(
self.fmt,
network_id)
self.assertIsNone(fip['floatingip'].get('port_id'))
res = self._create_fip_port_forwarding(
self.fmt, fip['floatingip']['id'],
2222, 22,
'tcp',
port['port']['fixed_ips'][0]['ip_address'],
port['port']['id'],
description="blablablabla")
self.assertEqual(exc.HTTPCreated.code, res.status_int)
pf_body = self.deserialize(self.fmt, res)
self.assertEqual(
"blablablabla", pf_body['port_forwarding']['description'])
def test_create_floatingip_port_forwarding_with_ranges(self):
internal_port_range = '22:24'
external_port_range = '2222:2224'
with self.network() as ext_net:
network_id = ext_net['network']['id']
self._set_net_external(network_id)
with self.subnet(ext_net, cidr='10.10.10.0/24'), \
self.router() as router, \
self.subnet(cidr='11.0.0.0/24') as private_subnet, \
self.port(private_subnet) as port:
self._add_external_gateway_to_router(
router['router']['id'],
network_id)
self._router_interface_action(
'add', router['router']['id'],
private_subnet['subnet']['id'],
None)
fip = self._make_floatingip(
self.fmt,
network_id)
self.assertIsNone(fip['floatingip'].get('port_id'))
res = self._create_fip_port_forwarding(
self.fmt, fip['floatingip']['id'],
None, None,
'tcp',
port['port']['fixed_ips'][0]['ip_address'],
port['port']['id'],
internal_port_range=internal_port_range,
external_port_range=external_port_range)
self.assertEqual(exc.HTTPCreated.code, res.status_int)
pf_body = self.deserialize(self.fmt, res)
self.assertEqual(
internal_port_range,
pf_body['port_forwarding']['internal_port_range'])
self.assertEqual(
external_port_range,
pf_body['port_forwarding']['external_port_range'])
def test_create_floatingip_port_forwarding_with_ranges_port_collisions(
self):
internal_port_range1 = '22:24'
internal_port_range2 = '23:25'
external_port_range1 = '2222:2224'
external_port_range2 = '2223:2225'
with self.network() as ext_net:
network_id = ext_net['network']['id']
self._set_net_external(network_id)
with self.subnet(ext_net, cidr='10.10.10.0/24'), \
self.router() as router, \
self.subnet(cidr='11.0.0.0/24') as private_subnet, \
self.port(private_subnet) as port:
self._add_external_gateway_to_router(
router['router']['id'],
network_id)
self._router_interface_action(
'add', router['router']['id'],
private_subnet['subnet']['id'],
None)
fip = self._make_floatingip(
self.fmt,
network_id)
self.assertIsNone(fip['floatingip'].get('port_id'))
self._create_fip_port_forwarding(
self.fmt, fip['floatingip']['id'],
None, None,
'tcp',
port['port']['fixed_ips'][0]['ip_address'],
port['port']['id'],
internal_port_range=internal_port_range1,
external_port_range=external_port_range1)
response = self._create_fip_port_forwarding(
self.fmt, fip['floatingip']['id'],
None, None,
'tcp',
port['port']['fixed_ips'][0]['ip_address'],
port['port']['id'],
internal_port_range=internal_port_range2,
external_port_range=external_port_range2)
self.assertEqual(exc.HTTPBadRequest.code,
response.status_int)
def test_update_floatingip_port_forwarding_with_dup_internal_port(self):
with self.network() as ext_net:
network_id = ext_net['network']['id']
self._set_net_external(network_id)
with self.subnet(ext_net, cidr='10.10.10.0/24'), \
self.router() as router, \
self.subnet(cidr='11.0.0.0/24') as private_subnet, \
self.port(private_subnet) as port:
self._add_external_gateway_to_router(
router['router']['id'],
network_id)
self._router_interface_action(
'add', router['router']['id'],
private_subnet['subnet']['id'],
None)
fip1 = self._make_floatingip(
self.fmt,
network_id)
self.assertIsNone(fip1['floatingip'].get('port_id'))
self._create_fip_port_forwarding(
self.fmt, fip1['floatingip']['id'],
2222, 22,
'tcp',
port['port']['fixed_ips'][0]['ip_address'],
port['port']['id'],
description="blablablabla")
fip2 = self._make_floatingip(
self.fmt,
network_id)
fip_pf_response = self._create_fip_port_forwarding(
self.fmt, fip2['floatingip']['id'],
2222, 23,
'tcp',
port['port']['fixed_ips'][0]['ip_address'],
port['port']['id'],
description="blablablabla")
update_res = self._update_fip_port_forwarding(
self.fmt, fip2['floatingip']['id'],
fip_pf_response.json['port_forwarding']['id'],
**{'internal_port': 22})
self.assertEqual(exc.HTTPBadRequest.code,
update_res.status_int)