Merge "Add Tap Mirrors to SDK"

This commit is contained in:
Zuul 2024-04-17 10:37:15 +00:00 committed by Gerrit Code Review
commit a39bc3c855
9 changed files with 292 additions and 2 deletions

View File

@ -357,3 +357,11 @@ SFC operations
update_sfc_port_pair_group, create_sfc_service_graph,
delete_sfc_service_graph, find_sfc_service_graph,
get_sfc_service_graph, update_sfc_service_graph
Tap Mirror operations
^^^^^^^^^^^^^^^^^^^^^
.. autoclass:: openstack.network.v2._proxy.Proxy
:noindex:
:members: create_tap_mirror, delete_tap_mirror, find_tap_mirror,
get_tap_mirror, tap_mirrors, update_tap_mirror

View File

@ -0,0 +1,12 @@
openstack.network.v2.tap_mirror
===============================
.. automodule:: openstack.network.v2.tap_mirror
The TapMirror Class
-------------------
The ``TapMirror`` class inherits from :class:`~openstack.resource.Resource`.
.. autoclass:: openstack.network.v2.tap_mirror.TapMirror
:members:

View File

@ -89,6 +89,7 @@ from openstack.network.v2 import sfc_service_graph as _sfc_sservice_graph
from openstack.network.v2 import subnet as _subnet
from openstack.network.v2 import subnet_pool as _subnet_pool
from openstack.network.v2 import tap_flow as _tap_flow
from openstack.network.v2 import tap_mirror as _tap_mirror
from openstack.network.v2 import tap_service as _tap_service
from openstack.network.v2 import trunk as _trunk
from openstack.network.v2 import vpn_endpoint_group as _vpn_endpoint_group
@ -178,6 +179,7 @@ class Proxy(proxy.Proxy):
"subnet": _subnet.Subnet,
"subnet_pool": _subnet_pool.SubnetPool,
"tap_flow": _tap_flow.TapFlow,
"tap_mirror": _tap_mirror.TapMirror,
"tap_service": _tap_service.TapService,
"trunk": _trunk.Trunk,
"vpn_endpoint_group": _vpn_endpoint_group.VpnEndpointGroup,
@ -6328,6 +6330,37 @@ class Proxy(proxy.Proxy):
"""Return a generator of Tap Flows"""
return self._list(_tap_flow.TapFlow, **query)
def create_tap_mirror(self, **attrs):
"""Create a new Tap Mirror from attributes"""
return self._create(_tap_mirror.TapMirror, **attrs)
def delete_tap_mirror(self, tap_mirror, ignore_missing=True):
"""Delete a Tap Mirror"""
self._delete(
_tap_mirror.TapMirror, tap_mirror, ignore_missing=ignore_missing
)
def find_tap_mirror(self, name_or_id, ignore_missing=True, **query):
"""Find a single Tap Mirror"""
return self._find(
_tap_mirror.TapMirror,
name_or_id,
ignore_missing=ignore_missing,
**query,
)
def get_tap_mirror(self, tap_mirror):
"""Get a signle Tap Mirror"""
return self._get(_tap_mirror.TapMirror, tap_mirror)
def update_tap_mirror(self, tap_mirror, **attrs):
"""Update a Tap Mirror"""
return self._update(_tap_mirror.TapMirror, tap_mirror, **attrs)
def tap_mirrors(self, **query):
"""Return a generator of Tap Mirrors"""
return self._list(_tap_mirror.TapMirror, **query)
def create_tap_service(self, **attrs):
"""Create a new Tap Service from attributes"""
return self._create(_tap_service.TapService, **attrs)

View File

@ -0,0 +1,54 @@
# 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 openstack import resource
class TapMirror(resource.Resource):
"""Tap Mirror"""
resource_key = 'tap_mirror'
resources_key = 'tap_mirrors'
base_path = '/taas/tap_mirrors'
# capabilities
allow_create = True
allow_fetch = True
allow_commit = True
allow_delete = True
allow_list = True
_allow_unknown_attrs_in_body = True
_query_mapping = resource.QueryParameters(
"sort_key", "sort_dir", 'name', 'project_id'
)
# Properties
#: The ID of the Tap Mirror.
id = resource.Body('id')
#: The Tap Mirror name.
name = resource.Body('name')
#: The Tap Mirror description.
description = resource.Body('description')
#: The ID of the project that owns the Tap Mirror.
project_id = resource.Body('project_id', alias='tenant_id')
#: Tenant_id (deprecated attribute).
tenant_id = resource.Body('tenant_id', deprecated=True)
#: The id of the port the Tap Mirror is associated with
port_id = resource.Body('port_id')
#: The status for the tap service.
directions = resource.Body('directions')
#: The destination IP address of the Tap Mirror
remote_ip = resource.Body('remote_ip')
#: The type of the Tap Mirror, it can be gre or erspanv1
mirror_type = resource.Body('mirror_type')

View File

@ -0,0 +1,83 @@
# 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 openstack.network.v2 import network as _network
from openstack.network.v2 import port as _port
from openstack.network.v2 import tap_mirror as _tap_mirror
from openstack.tests.functional import base
class TestTapMirror(base.BaseFunctionalTest):
def setUp(self):
super().setUp()
if not self.user_cloud.network.find_extension("tap-mirror"):
self.skipTest("Neutron Tap Mirror Extension disabled")
self.TAP_M_NAME = 'my_tap_mirror' + self.getUniqueString()
net = self.user_cloud.network.create_network()
assert isinstance(net, _network.Network)
self.MIRROR_NET_ID = net.id
port = self.user_cloud.network.create_port(
network_id=self.MIRROR_NET_ID
)
assert isinstance(port, _port.Port)
self.MIRROR_PORT_ID = port.id
self.REMOTE_IP = '193.10.10.2'
self.MIRROR_TYPE = 'erspanv1'
tap_mirror = self.user_cloud.network.create_tap_mirror(
name=self.TAP_M_NAME,
port_id=self.MIRROR_PORT_ID,
remote_ip=self.REMOTE_IP,
mirror_type=self.MIRROR_TYPE,
directions={'IN': 99},
)
assert isinstance(tap_mirror, _tap_mirror.TapMirror)
self.TAP_MIRROR = tap_mirror
def tearDown(self):
sot = self.user_cloud.network.delete_tap_mirror(
self.TAP_MIRROR.id, ignore_missing=False
)
self.assertIsNone(sot)
sot = self.user_cloud.network.delete_port(self.MIRROR_PORT_ID)
self.assertIsNone(sot)
sot = self.user_cloud.network.delete_network(self.MIRROR_NET_ID)
self.assertIsNone(sot)
super().tearDown()
def test_find_tap_mirror(self):
sot = self.user_cloud.network.find_tap_mirror(self.TAP_MIRROR.name)
self.assertEqual(self.MIRROR_PORT_ID, sot.port_id)
self.assertEqual(self.TAP_M_NAME, sot.name)
def test_get_tap_mirror(self):
sot = self.user_cloud.network.get_tap_mirror(self.TAP_MIRROR.id)
self.assertEqual(self.MIRROR_PORT_ID, sot.port_id)
self.assertEqual(self.TAP_M_NAME, sot.name)
def test_list_tap_mirrors(self):
tap_mirror_ids = [
tm.id for tm in self.user_cloud.network.tap_mirrors()
]
self.assertIn(self.TAP_MIRROR.id, tap_mirror_ids)
def test_update_tap_mirror(self):
description = 'My Tap Mirror'
sot = self.user_cloud.network.update_tap_mirror(
self.TAP_MIRROR.id, description=description
)
self.assertEqual(description, sot.description)

View File

@ -64,6 +64,7 @@ from openstack.network.v2 import service_profile
from openstack.network.v2 import service_provider
from openstack.network.v2 import subnet
from openstack.network.v2 import subnet_pool
from openstack.network.v2 import tap_mirror
from openstack.network.v2 import vpn_endpoint_group
from openstack.network.v2 import vpn_ike_policy
from openstack.network.v2 import vpn_ipsec_policy
@ -2638,3 +2639,30 @@ class TestNetworkBGPVPN(TestNetworkProxy):
expected_args=[self.ROUTER_ASSOCIATION],
expected_kwargs={'bgpvpn_id': BGPVPN_ID},
)
class TestNetworkTapMirror(TestNetworkProxy):
def test_create_tap_mirror(self):
self.verify_create(self.proxy.create_tap_mirror, tap_mirror.TapMirror)
def test_delete_tap_mirror(self):
self.verify_delete(
self.proxy.delete_tap_mirror, tap_mirror.TapMirror, False
)
def test_delete_tap_mirror_ignore(self):
self.verify_delete(
self.proxy.delete_tap_mirror, tap_mirror.TapMirror, True
)
def test_find_tap_mirror(self):
self.verify_find(self.proxy.find_tap_mirror, tap_mirror.TapMirror)
def test_get_tap_mirror(self):
self.verify_get(self.proxy.get_tap_mirror, tap_mirror.TapMirror)
def test_tap_mirrors(self):
self.verify_list(self.proxy.tap_mirrors, tap_mirror.TapMirror)
def test_update_tap_mirror(self):
self.verify_update(self.proxy.update_tap_mirror, tap_mirror.TapMirror)

View File

@ -0,0 +1,62 @@
# 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 openstack.network.v2 import tap_mirror
from openstack.tests.unit import base
IDENTIFIER = 'IDENTIFIER'
PORT_ID = 'PORT_ID'
EXAMPLE = {
'name': 'my_tap_mirror',
'port_id': PORT_ID,
'directions': {'IN': 99},
'remote_ip': '193.10.10.1',
'mirror_type': 'erspanv1',
'id': IDENTIFIER,
'project_id': '42',
}
class TestTapMirror(base.TestCase):
def test_basic(self):
sot = tap_mirror.TapMirror()
self.assertEqual('tap_mirror', sot.resource_key)
self.assertEqual('tap_mirrors', sot.resources_key)
self.assertEqual('/taas/tap_mirrors', sot.base_path)
self.assertTrue(sot.allow_create)
self.assertTrue(sot.allow_fetch)
self.assertTrue(sot.allow_commit)
self.assertTrue(sot.allow_delete)
self.assertTrue(sot.allow_list)
def test_make_it(self):
sot = tap_mirror.TapMirror(**EXAMPLE)
self.assertEqual(EXAMPLE['name'], sot.name)
self.assertEqual(EXAMPLE['port_id'], sot.port_id)
self.assertEqual(EXAMPLE['directions'], sot.directions)
self.assertEqual(EXAMPLE['remote_ip'], sot.remote_ip)
self.assertEqual(EXAMPLE['mirror_type'], sot.mirror_type)
self.assertEqual(EXAMPLE['id'], sot.id)
self.assertEqual(EXAMPLE['project_id'], sot.project_id)
self.assertDictEqual(
{
'limit': 'limit',
'marker': 'marker',
'name': 'name',
'project_id': 'project_id',
'sort_key': 'sort_key',
'sort_dir': 'sort_dir',
},
sot._query_mapping._mapping,
)

View File

@ -0,0 +1,5 @@
---
features:
- |
Add ``Tap Mirror`` and introduce the support for creating, reading,
updating and deleting ``tap_mirrors``.

View File

@ -152,6 +152,7 @@
required-projects:
- openstack/neutron-fwaas
- openstack/neutron-vpnaas
- openstack/tap-as-a-service
vars:
INSTALL_OVN: False
configure_swap_size: 4096
@ -184,17 +185,19 @@
agent:
availability_zone: nova
devstack_localrc:
Q_SERVICE_PLUGIN_CLASSES: qos,trunk
NETWORK_API_EXTENSIONS: "agent,binding,dhcp_agent_scheduler,external-net,ext-gw-mode,extra_dhcp_opts,quotas,router,security-group,subnet_allocation,network-ip-availability,auto-allocated-topology,timestamp_core,tag,service-type,rbac-policies,standard-attr-description,pagination,sorting,project-id,fwaas_v2,vpnaas"
Q_SERVICE_PLUGIN_CLASSES: qos,trunk,taas
NETWORK_API_EXTENSIONS: "agent,binding,dhcp_agent_scheduler,external-net,ext-gw-mode,extra_dhcp_opts,quotas,router,security-group,subnet_allocation,network-ip-availability,auto-allocated-topology,timestamp_core,tag,service-type,rbac-policies,standard-attr-description,pagination,sorting,project-id,fwaas_v2,vpnaas,taas,tap_mirror"
Q_AGENT: openvswitch
Q_ML2_TENANT_NETWORK_TYPE: vxlan
Q_ML2_PLUGIN_MECHANISM_DRIVERS: openvswitch
IPSEC_PACKAGE: libreswan
TAAS_SERVICE_DRIVER: TAAS:TAAS:neutron_taas.services.taas.service_drivers.taas_rpc.TaasRpcDriver:default
devstack_plugins:
designate: https://opendev.org/openstack/designate
octavia: https://opendev.org/openstack/octavia
neutron-fwaas: https://opendev.org/openstack/neutron-fwaas.git
neutron-vpnaas: https://opendev.org/openstack/neutron-vpnaas.git
tap-as-a-service: https://opendev.org/openstack/tap-as-a-service.git
devstack_services:
designate: true
octavia: true
@ -211,6 +214,8 @@
h-api: false
h-api-cfn: false
q-fwaas-v2: true
taas: true
tap_mirror: true
tox_environment:
OPENSTACKSDK_HAS_DESIGNATE: 1
OPENSTACKSDK_HAS_SWIFT: 0