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,
|
update_sfc_port_pair_group, create_sfc_service_graph,
|
||||||
delete_sfc_service_graph, find_sfc_service_graph,
|
delete_sfc_service_graph, find_sfc_service_graph,
|
||||||
get_sfc_service_graph, update_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 as _subnet
|
||||||
from openstack.network.v2 import subnet_pool as _subnet_pool
|
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_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 tap_service as _tap_service
|
||||||
from openstack.network.v2 import trunk as _trunk
|
from openstack.network.v2 import trunk as _trunk
|
||||||
from openstack.network.v2 import vpn_endpoint_group as _vpn_endpoint_group
|
from openstack.network.v2 import vpn_endpoint_group as _vpn_endpoint_group
|
||||||
@ -178,6 +179,7 @@ class Proxy(proxy.Proxy):
|
|||||||
"subnet": _subnet.Subnet,
|
"subnet": _subnet.Subnet,
|
||||||
"subnet_pool": _subnet_pool.SubnetPool,
|
"subnet_pool": _subnet_pool.SubnetPool,
|
||||||
"tap_flow": _tap_flow.TapFlow,
|
"tap_flow": _tap_flow.TapFlow,
|
||||||
|
"tap_mirror": _tap_mirror.TapMirror,
|
||||||
"tap_service": _tap_service.TapService,
|
"tap_service": _tap_service.TapService,
|
||||||
"trunk": _trunk.Trunk,
|
"trunk": _trunk.Trunk,
|
||||||
"vpn_endpoint_group": _vpn_endpoint_group.VpnEndpointGroup,
|
"vpn_endpoint_group": _vpn_endpoint_group.VpnEndpointGroup,
|
||||||
@ -6328,6 +6330,37 @@ class Proxy(proxy.Proxy):
|
|||||||
"""Return a generator of Tap Flows"""
|
"""Return a generator of Tap Flows"""
|
||||||
return self._list(_tap_flow.TapFlow, **query)
|
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):
|
def create_tap_service(self, **attrs):
|
||||||
"""Create a new Tap Service from attributes"""
|
"""Create a new Tap Service from attributes"""
|
||||||
return self._create(_tap_service.TapService, **attrs)
|
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 service_provider
|
||||||
from openstack.network.v2 import subnet
|
from openstack.network.v2 import subnet
|
||||||
from openstack.network.v2 import subnet_pool
|
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_endpoint_group
|
||||||
from openstack.network.v2 import vpn_ike_policy
|
from openstack.network.v2 import vpn_ike_policy
|
||||||
from openstack.network.v2 import vpn_ipsec_policy
|
from openstack.network.v2 import vpn_ipsec_policy
|
||||||
@ -2638,3 +2639,30 @@ class TestNetworkBGPVPN(TestNetworkProxy):
|
|||||||
expected_args=[self.ROUTER_ASSOCIATION],
|
expected_args=[self.ROUTER_ASSOCIATION],
|
||||||
expected_kwargs={'bgpvpn_id': BGPVPN_ID},
|
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:
|
required-projects:
|
||||||
- openstack/neutron-fwaas
|
- openstack/neutron-fwaas
|
||||||
- openstack/neutron-vpnaas
|
- openstack/neutron-vpnaas
|
||||||
|
- openstack/tap-as-a-service
|
||||||
vars:
|
vars:
|
||||||
INSTALL_OVN: False
|
INSTALL_OVN: False
|
||||||
configure_swap_size: 4096
|
configure_swap_size: 4096
|
||||||
@ -184,17 +185,19 @@
|
|||||||
agent:
|
agent:
|
||||||
availability_zone: nova
|
availability_zone: nova
|
||||||
devstack_localrc:
|
devstack_localrc:
|
||||||
Q_SERVICE_PLUGIN_CLASSES: qos,trunk
|
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"
|
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_AGENT: openvswitch
|
||||||
Q_ML2_TENANT_NETWORK_TYPE: vxlan
|
Q_ML2_TENANT_NETWORK_TYPE: vxlan
|
||||||
Q_ML2_PLUGIN_MECHANISM_DRIVERS: openvswitch
|
Q_ML2_PLUGIN_MECHANISM_DRIVERS: openvswitch
|
||||||
IPSEC_PACKAGE: libreswan
|
IPSEC_PACKAGE: libreswan
|
||||||
|
TAAS_SERVICE_DRIVER: TAAS:TAAS:neutron_taas.services.taas.service_drivers.taas_rpc.TaasRpcDriver:default
|
||||||
devstack_plugins:
|
devstack_plugins:
|
||||||
designate: https://opendev.org/openstack/designate
|
designate: https://opendev.org/openstack/designate
|
||||||
octavia: https://opendev.org/openstack/octavia
|
octavia: https://opendev.org/openstack/octavia
|
||||||
neutron-fwaas: https://opendev.org/openstack/neutron-fwaas.git
|
neutron-fwaas: https://opendev.org/openstack/neutron-fwaas.git
|
||||||
neutron-vpnaas: https://opendev.org/openstack/neutron-vpnaas.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:
|
devstack_services:
|
||||||
designate: true
|
designate: true
|
||||||
octavia: true
|
octavia: true
|
||||||
@ -211,6 +214,8 @@
|
|||||||
h-api: false
|
h-api: false
|
||||||
h-api-cfn: false
|
h-api-cfn: false
|
||||||
q-fwaas-v2: true
|
q-fwaas-v2: true
|
||||||
|
taas: true
|
||||||
|
tap_mirror: true
|
||||||
tox_environment:
|
tox_environment:
|
||||||
OPENSTACKSDK_HAS_DESIGNATE: 1
|
OPENSTACKSDK_HAS_DESIGNATE: 1
|
||||||
OPENSTACKSDK_HAS_SWIFT: 0
|
OPENSTACKSDK_HAS_SWIFT: 0
|
||||||
|
Loading…
Reference in New Issue
Block a user