Add Tap Mirrors to SDK
Depends-On: https://review.opendev.org/c/893086 Change-Id: If8151ebe82c3991c9cd2fed57ecb7723ab3db97c Related-Bug: #2015471
This commit is contained in:
parent
4d9c40b74c
commit
be6699639c
@ -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
|
||||
|
12
doc/source/user/resources/network/v2/tap_mirror.rst
Normal file
12
doc/source/user/resources/network/v2/tap_mirror.rst
Normal 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:
|
@ -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)
|
||||
|
54
openstack/network/v2/tap_mirror.py
Normal file
54
openstack/network/v2/tap_mirror.py
Normal 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')
|
83
openstack/tests/functional/network/v2/test_tap_mirror.py
Normal file
83
openstack/tests/functional/network/v2/test_tap_mirror.py
Normal 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)
|
@ -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)
|
||||
|
62
openstack/tests/unit/network/v2/test_tap_mirror.py
Normal file
62
openstack/tests/unit/network/v2/test_tap_mirror.py
Normal 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,
|
||||
)
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Add ``Tap Mirror`` and introduce the support for creating, reading,
|
||||
updating and deleting ``tap_mirrors``.
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user