Add SFC to SDK

Included resources are:
* PortChain
* PortPairGroup
* PortPair
* FlowClassifier
* ServiceGraph

api-ref (under review):
https://review.opendev.org/c/openstack/neutron-lib/+/887193

Related-Bug: #1999774
Change-Id: I254fadb780798fec65e41e8d95719f38cc1e0601
This commit is contained in:
elajkat 2023-06-28 17:29:05 +02:00
parent 42ae7989c5
commit 16c114dd66
20 changed files with 1405 additions and 0 deletions

View File

@ -329,3 +329,20 @@ BGPVPN operations
bgpvpn_port_associations, create_bgpvpn_router_association,
delete_bgpvpn_router_association, get_bgpvpn_router_association,
update_bgpvpn_router_association, bgpvpn_router_associations
SFC operations
^^^^^^^^^^^^^^
.. autoclass:: openstack.network.v2._proxy.Proxy
:noindex:
:members: create_sfc_flow_classifier, delete_sfc_flow_classifier,
find_sfc_flow_classifier, get_sfc_flow_classifier,
update_sfc_flow_classifier, create_sfc_port_chain,
delete_sfc_port_chain, find_sfc_port_chain, get_sfc_port_chain,
update_sfc_port_chain, create_sfc_port_pair, delete_sfc_port_pair,
find_sfc_port_pair, get_sfc_port_pair, update_sfc_port_pair,
create_sfc_port_pair_group, delete_sfc_port_pair_group,
find_sfc_port_pair_group, get_sfc_port_pair_group,
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

View File

@ -46,6 +46,11 @@ Network Resources
v2/segment
v2/service_profile
v2/service_provider
v2/sfc_flow_classifier
v2/sfc_port_chain
v2/sfc_port_pair_group
v2/sfc_port_pair
v2/sfc_service_graph
v2/subnet
v2/subnet_pool
v2/tap_flow

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -80,6 +80,11 @@ from openstack.network.v2 import security_group_rule as _security_group_rule
from openstack.network.v2 import segment as _segment
from openstack.network.v2 import service_profile as _service_profile
from openstack.network.v2 import service_provider as _service_provider
from openstack.network.v2 import sfc_flow_classifier as _sfc_flow_classifier
from openstack.network.v2 import sfc_port_chain as _sfc_port_chain
from openstack.network.v2 import sfc_port_pair as _sfc_port_pair
from openstack.network.v2 import sfc_port_pair_group as _sfc_port_pair_group
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
@ -162,6 +167,11 @@ class Proxy(proxy.Proxy, Generic[T]):
"segment": _segment.Segment,
"service_profile": _service_profile.ServiceProfile,
"service_provider": _service_provider.ServiceProvider,
"sfc_flow_classifier": _sfc_flow_classifier.SfcFlowClassifier,
"sfc_port_chain": _sfc_port_chain.SfcPortChain,
"sfc_port_pair": _sfc_port_pair.SfcPortPair,
"sfc_port_pair_group": _sfc_port_pair_group.SfcPortPairGroup,
"sfc_service_graph": _sfc_sservice_graph.SfcServiceGraph,
"subnet": _subnet.Subnet,
"subnet_pool": _subnet_pool.SubnetPool,
"tap_flow": _tap_flow.TapFlow,
@ -6202,6 +6212,523 @@ class Proxy(proxy.Proxy, Generic[T]):
"""Return a generator of Tap Services"""
return self._list(_tap_service.TapService, **query)
def create_sfc_flow_classifier(self, **attrs):
"""Create a new Flow Classifier from attributes
:param attrs: Keyword arguments which will be used to create a
:class:`~openstack.network.v2.sfc_flow_classifier.SfcFlowClassifier`,
comprised of the properties on the SfcFlowClassifier class.
:returns: The results of SFC Flow Classifier creation
:rtype:
:class:`~openstack.network.v2.sfc_flow_classifier.SfcFlowClassifier`
"""
return self._create(_sfc_flow_classifier.SfcFlowClassifier, **attrs)
def delete_sfc_flow_classifier(self, flow_classifier, ignore_missing=True):
"""Delete a Flow Classifier
:param flow_classifier:
The value can be either the ID of a flow classifier or a
:class:`~openstack.network.v2.sfc_flow_classifier.SfcFlowClassifier`
instance.
:param bool ignore_missing: When set to ``False``
:class:`~openstack.exceptions.ResourceNotFound` will be
raised when the flow classifier does not exist.
When set to ``True``, no exception will be set when
attempting to delete a nonexistent flow classifier.
:returns: ``None``
"""
self._delete(
_sfc_flow_classifier.SfcFlowClassifier,
flow_classifier,
ignore_missing=ignore_missing,
)
def find_sfc_flow_classifier(
self, name_or_id, ignore_missing=True, **query
):
"""Find a single Flow Classifier
:param str name_or_id: The name or ID of an SFC flow classifier.
:param bool ignore_missing: When set to ``False``
:class:`~openstack.exceptions.ResourceNotFound` will be
raised when the resource does not exist.
When set to ``True``, None will be returned when
attempting to find a nonexistent resource.
:param dict query: Any additional parameters to be passed into
underlying methods. such as query filters.
:returns: One
:class:`~openstack.network.v2.sfc_flow_classifier.
SfcFlowClassifier` or None
"""
return self._find(
_sfc_flow_classifier.SfcFlowClassifier,
name_or_id,
ignore_missing=ignore_missing,
**query,
)
def get_sfc_flow_classifier(self, flow_classifier):
"""Get a single Flow Classifier
:param flow_classifier:
The value can be the ID of an SFC flow classifier or a
:class:`~openstack.network.v2.sfc_flow_classifier.SfcFlowClassifier` instance.
:returns:
:class:`~openstack.network.v2.sfc_flow_classifier.SfcFlowClassifier`
:raises: :class:`~openstack.exceptions.ResourceNotFound`
when no resource can be found.
"""
return self._get(
_sfc_flow_classifier.SfcFlowClassifier, flow_classifier
)
def update_sfc_flow_classifier(self, flow_classifier, **attrs):
"""Update a Flow Classifier
:param flow_classifier: The value can be the ID of a Flow Classifier
:class:`~openstack.network.v2.sfc_flow_classifier.SfcFlowClassifier`,
instance.
:param attrs: The attributes to update on the Flow Classifier
:returns: The updated Flow Classifier.
:rtype:
:class:`~openstack.network.v2.sfc_flow_classifier.SfcFlowClassifier`
"""
return self._update(
_sfc_flow_classifier.SfcFlowClassifier, flow_classifier, **attrs
)
def sfc_flow_classifiers(self, **query):
"""Return a generator of Flow Classifiers
:param kwargs query: Optional query parameters to be sent to limit
the resources being returned. Available parameters include:
* ``name``: The name of the flow classifier.
* ``description``: The flow classifier description
* ``ethertype``: Must be IPv4 or IPv6.
* ``protocol``: Flow classifier protocol
:returns: A generator of SFC Flow classifier objects
:rtype:
:class:`~openstack.network.v2.sfc_flow_classifier.
SfcFlowClassifier`
"""
return self._list(_sfc_flow_classifier.SfcFlowClassifier, **query)
def create_sfc_port_chain(self, **attrs):
"""Create a new Port Chain from attributes
:param attrs: Keyword arguments which will be used to create a
:class:`~openstack.network.v2.sfc_port_chain.SfcPortChain`,
comprised of the properties on the SfcPortchain class.
:returns: The results of SFC Port Chain creation
:rtype:
:class:`~openstack.network.v2.sfc_port_chain.SfcPortChain`
"""
return self._create(_sfc_port_chain.SfcPortChain, **attrs)
def delete_sfc_port_chain(self, port_chain, ignore_missing=True):
"""Delete a Port Chain
:param port_chain:
The value can be either the ID of a port chain or a
:class:`~openstack.network.v2.sfc_port_chain.SfcPortChain`
instance.
:param bool ignore_missing: When set to ``False``
:class:`~openstack.exceptions.ResourceNotFound` will be
raised when the port chain does not exist.
When set to ``True``, no exception will be set when
attempting to delete a nonexistent port chain.
:returns: ``None``
"""
self._delete(
_sfc_port_chain.SfcPortChain,
port_chain,
ignore_missing=ignore_missing,
)
def find_sfc_port_chain(self, name_or_id, ignore_missing=True, **query):
"""Find a single Port Chain
:param str name_or_id: The name or ID of an SFC port chain.
:param bool ignore_missing: When set to ``False``
:class:`~openstack.exceptions.ResourceNotFound` will be
raised when the resource does not exist.
When set to ``True``, None will be returned when
attempting to find a nonexistent resource.
:param dict query: Any additional parameters to be passed into
underlying methods. such as query filters.
:returns: One
:class:`~openstack.network.v2.sfc_port_chain.
SfcPortChain` or None
"""
return self._find(
_sfc_port_chain.SfcPortChain,
name_or_id,
ignore_missing=ignore_missing,
**query,
)
def get_sfc_port_chain(self, port_chain):
"""Get a signle Port Chain
:param port_chain:
The value can be the ID of an SFC port chain or a
:class:`~openstack.network.v2.sfc_port_chain.SfcPortChain`
instance.
:returns:
:class:`~openstack.network.v2.sfc_port_chain.SfcPortchain`
:raises: :class:`~openstack.exceptions.ResourceNotFound`
when no resource can be found.
"""
return self._get(_sfc_port_chain.SfcPortChain, port_chain)
def update_sfc_port_chain(self, port_chain, **attrs):
"""Update a Port Chain
:param flow_classifier: The value can be the ID of a Flow Classifier
:class:`~openstack.network.v2.sfc_flow_classifier.SfcFlowClassifier`,
instance.
:param attrs: The attributes to update on the Flow Classifier
:returns: The updated Flow Classifier.
:rtype:
:class:`~openstack.network.v2.sfc_flow_classifier.SfcFlowClassifier`
"""
return self._update(_sfc_port_chain.SfcPortChain, port_chain, **attrs)
def sfc_port_chains(self, **query):
"""Return a generator of Port Chains
:param kwargs query: Optional query parameters to be sent to limit
the resources being returned. Available parameters include:
* ``name``: The name of the port chain
* ``description``: The port chain description
:returns: A generator of SFC port chain objects
:rtype:
:class:`~openstack.network.v2.sfc_port_chain.SfcPortChain`
"""
return self._list(_sfc_port_chain.SfcPortChain, **query)
def create_sfc_port_pair(self, **attrs):
"""Create a new Port Pair from attributes
:param attrs: Keyword arguments which will be used to create a
:class:`~openstack.network.v2.sfc_port_pair.SfcPortPair`,
comprised of the properties on the SfcPortPair class.
:returns: The results of SFC Port Pair creation
:rtype:
:class:`~openstack.network.v2.sfc_port_pair.SfPortPair`
"""
return self._create(_sfc_port_pair.SfcPortPair, **attrs)
def delete_sfc_port_pair(self, port_pair, ignore_missing=True):
"""Delete a Port Pair
:param port_pair:
The value can be either the ID of a port pair or a
:class:`~openstack.network.v2.sfc_port_pair.SfcPortPair`
instance.
:param bool ignore_missing: When set to ``False``
:class:`~openstack.exceptions.ResourceNotFound` will be
raised when the port pair does not exist.
When set to ``True``, no exception will be set when
attempting to delete a nonexistent port pair.
:returns: ``None``
"""
self._delete(
_sfc_port_pair.SfcPortPair,
port_pair,
ignore_missing=ignore_missing,
)
def find_sfc_port_pair(self, name_or_id, ignore_missing=True, **query):
"""Find a single Port Pair
:param str name_or_id: The name or ID of an SFC port pair.
:param bool ignore_missing: When set to ``False``
:class:`~openstack.exceptions.ResourceNotFound` will be
raised when the resource does not exist.
When set to ``True``, None will be returned when
attempting to find a nonexistent resource.
:param dict query: Any additional parameters to be passed into
underlying methods. such as query filters.
:returns: One
:class:`~openstack.network.v2.sfc_port_pair.SfcPortPair` or None
"""
return self._find(
_sfc_port_pair.SfcPortPair,
name_or_id,
ignore_missing=ignore_missing,
**query,
)
def get_sfc_port_pair(self, port_pair):
"""Get a signle Port Pair
:param port_pair:
The value can be the ID of an SFC port pair or a
:class:`~openstack.network.v2.sfc_port_pair.SfcPortPair`
instance.
:returns:
:class:`~openstack.network.v2.sfc_port_pair.SfcPortPair`
:raises: :class:`~openstack.exceptions.ResourceNotFound`
when no resource can be found.
"""
return self._get(_sfc_port_pair.SfcPortPair, port_pair)
def update_sfc_port_pair(self, port_pair, **attrs):
"""Update a Port Pair
:param port_pair: The value can be the ID of a Port Pair
:class:`~openstack.network.v2.sfc_port_pair.SfcPortPair`,
instance.
:param attrs: The attributes to update on the Port Pair
:returns: The updated Port Pair.
:rtype:
:class:`~openstack.network.v2.sfc_port_pair.SfcPortPair`
"""
return self._update(_sfc_port_pair.SfcPortPair, port_pair, **attrs)
def sfc_port_pairs(self, **query):
"""Return a generator of Port Pairs
:param kwargs query: Optional query parameters to be sent to limit
the resources being returned. Available parameters include:
* ``name``: The name of the port pair.
* ``description``: The port pair description.
:returns: A generator of SFC port pair objects
:rtype:
:class:`~openstack.network.v2.sfc_port_pair.SfcPortPair`
"""
return self._list(_sfc_port_pair.SfcPortPair, **query)
def create_sfc_port_pair_group(self, **attrs):
"""Create a new Port Pair Group from attributes
:param attrs: Keyword arguments which will be used to create a
:class:`~openstack.network.v2.sfc_port_pair_group.SfcPortPairGroup`,
comprised of the properties on the SfcPortPairGroup class.
:returns: The results of SFC Port Pair Group creation
:rtype:
:class:`~openstack.network.v2.sfc_port_pair_group.SfcPortPairGroup`
"""
return self._create(_sfc_port_pair_group.SfcPortPairGroup, **attrs)
def delete_sfc_port_pair_group(self, port_pair_group, ignore_missing=True):
"""Delete a Port Pair Group
:param port_pair_group:
The value can be either the ID of a port pair group or a
:class:`~openstack.network.v2.sfc_port_pair_group.
SfcPortPairGroup` instance.
:param bool ignore_missing: When set to ``False``
:class:`~openstack.exceptions.ResourceNotFound` will be
raised when the port pair group does not exist.
When set to ``True``, no exception will be set when
attempting to delete a nonexistent port pair group.
:returns: ``None``
"""
self._delete(
_sfc_port_pair_group.SfcPortPairGroup,
port_pair_group,
ignore_missing=ignore_missing,
)
def find_sfc_port_pair_group(
self, name_or_id, ignore_missing=True, **query
):
"""Find a single Port Pair Group
:param str name_or_id: The name or ID of an SFC port pair group.
:param bool ignore_missing: When set to ``False``
:class:`~openstack.exceptions.ResourceNotFound` will be
raised when the resource does not exist.
When set to ``True``, None will be returned when
attempting to find a nonexistent resource.
:param dict query: Any additional parameters to be passed into
underlying methods. such as query filters.
:returns: One
:class:`~openstack.network.v2.sfc_port_pair_group.
SfcPortPairGroup` or None
"""
return self._find(
_sfc_port_pair_group.SfcPortPairGroup,
name_or_id,
ignore_missing=ignore_missing,
**query,
)
def get_sfc_port_pair_group(self, port_pair_group):
"""Get a signle Port Pair Group
:param port_pair_group:
The value can be the ID of an SFC port pair group or a
:class:`~openstack.network.v2.sfc_port_pair_group.SfcPortPairGroup`
instance.
:returns:
:class:`~openstack.network.v2.sfc_port_pair_group.SfcPortPairGroup`
:raises: :class:`~openstack.exceptions.ResourceNotFound`
when no resource can be found.
"""
return self._get(
_sfc_port_pair_group.SfcPortPairGroup, port_pair_group
)
def update_sfc_port_pair_group(self, port_pair_group, **attrs):
"""Update a Port Pair Group
:param port_pair_group: The value can be the ID of a Port Pair Group
:class:`~openstack.network.v2.sfc_port_pair.SfcPortPairGroup`,
instance.
:param attrs: The attributes to update on the Port Pair Group
:returns: The updated Port Pair Group.
:rtype:
:class:`~openstack.network.v2.sfc_port_pair_group.SfcPortPairGroup`
"""
return self._update(
_sfc_port_pair_group.SfcPortPairGroup, port_pair_group, **attrs
)
def sfc_port_pair_groups(self, **query):
"""Return a generator of Port Pair Groups
:param kwargs query: Optional query parameters to be sent to limit
the resources being returned. Available parameters include:
* ``name``: The name of the port pair.
* ``description``: The port pair description.
:returns: A generator of SFC port pair group objects
:rtype:
:class:`~openstack.network.v2.sfc_port_pair_group.
SfcPortPairGroup`
"""
return self._list(_sfc_port_pair_group.SfcPortPairGroup, **query)
def create_sfc_service_graph(self, **attrs):
"""Create a new Service Graph from attributes
:param attrs: Keyword arguments which will be used to create a
:class:`~openstack.network.v2.sfc_service_graph.SfcServiceGraph`,
comprised of the properties on the SfcServiceGraph class.
:returns: The results of SFC Service Graph creation
:rtype:
:class:`~openstack.network.v2.sfc_service_graph.SfcServiceGraph`
"""
return self._create(_sfc_sservice_graph.SfcServiceGraph, **attrs)
def delete_sfc_service_graph(self, service_graph, ignore_missing=True):
"""Delete a Service Graph
:param service_graph:
The value can be either the ID of a service graph or a
:class:`~openstack.network.v2.sfc_service_graph.SfcServiceGraph`
instance.
:param bool ignore_missing: When set to ``False``
:class:`~openstack.exceptions.ResourceNotFound` will be
raised when the service graph does not exist.
When set to ``True``, no exception will be set when
attempting to delete a nonexistent service graph.
:returns: ``None``
"""
self._delete(
_sfc_sservice_graph.SfcServiceGraph,
service_graph,
ignore_missing=ignore_missing,
)
def find_sfc_service_graph(self, name_or_id, ignore_missing=True, **query):
"""Find a single Service Graph
:param str name_or_id: The name or ID of an SFC service graph.
:param bool ignore_missing: When set to ``False``
:class:`~openstack.exceptions.ResourceNotFound` will be
raised when the resource does not exist.
When set to ``True``, None will be returned when
attempting to find a nonexistent resource.
:param dict query: Any additional parameters to be passed into
underlying methods. such as query filters.
:returns: One
:class:`~openstack.network.v2.sfc_service_graph.
SfcServiceGraph` or None
"""
return self._find(
_sfc_sservice_graph.SfcServiceGraph,
name_or_id,
ignore_missing=ignore_missing,
**query,
)
def get_sfc_service_graph(self, service_graph):
"""Get a signle Service Graph
:param service_graph:
The value can be the ID of an SFC service graph or a
:class:`~openstack.network.v2.sfc_service_graph.SfcServiceGraph`
instance.
:returns:
:class:`~openstack.network.v2.sfc_service_graph.SfcServiceGraph`
:raises: :class:`~openstack.exceptions.ResourceNotFound`
when no resource can be found.
"""
return self._get(_sfc_sservice_graph.SfcServiceGraph, service_graph)
def update_sfc_service_graph(self, service_graph, **attrs):
"""Update a Service Graph
:param service_graph: The value can be the ID of a Service Graph
:class:`~openstack.network.v2.sfc_service_graph.SfcServiceGraph`,
instance.
:param attrs: The attributes to update on the Service Graph
:returns: The updated Service Graph.
:rtype:
:class:`~openstack.network.v2.sfc_service_graph.SfcServiceGraph`
"""
return self._update(
_sfc_sservice_graph.SfcServiceGraph, service_graph, **attrs
)
def sfc_service_graphs(self, **query):
"""Return a generator of Service Graphs
:param kwargs query: Optional query parameters to be sent to limit
the resources being returned. Available parameters include:
* ``name``: The name of the port pair.
* ``description``: The port pair description.
:returns: A generator of SFC service graph objects
:rtype:
:class:`~openstack.network.v2.sfc_service_graph.SfcServiceGraph`
"""
return self._list(_sfc_sservice_graph.SfcServiceGraph, **query)
def _get_cleanup_dependencies(self):
return {'network': {'before': ['identity']}}

View File

@ -0,0 +1,88 @@
# 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 SfcFlowClassifier(resource.Resource):
resource_key = 'flow_classifier'
resources_key = 'flow_classifiers'
base_path = '/sfc/flow_classifiers'
# capabilities
allow_create = True
allow_fetch = True
allow_commit = True
allow_delete = True
allow_list = True
_query_mapping = resource.QueryParameters(
'description',
'name',
'project_id',
'tenant_id',
'ethertype',
'protocol',
'source_port_range_min',
'source_port_range_max',
'destination_port_range_min',
'destination_port_range_max',
'logical_source_port',
'logical_destination_port',
)
# Properties
#: Human-readable description for the resource.
description = resource.Body('description')
#: Human-readable name of the resource. Default is an empty string.
name = resource.Body('name')
#: Must be IPv4 or IPv6, and addresses represented in CIDR must match
# the ingress or egress rules.
ethertype = resource.Body('ethertype')
#: The IP protocol can be represented by a string, an integer, or null.
#: Valid values: any (0), ah (51), dccp (33), egp (8), esp (50), gre (47),
#: icmp (1), icmpv6 (58), igmp (2), ipip (4), ipv6-encap (41),
#: ipv6-frag (44), ipv6-icmp (58), ipv6-nonxt (59), ipv6-opts (60),
#: ipv6-route (43), ospf (89), pgm (113), rsvp (46), sctp (132), tcp (6),
#: udp (17), udplite (136), vrrp (112).
protocol = resource.Body('protocol')
#: Minimum source protocol port.
source_port_range_min = resource.Body('source_port_range_min', type=int)
#: Maximum source protocol port.
source_port_range_max = resource.Body('source_port_range_max', type=int)
#: Minimum destination protocol port.
destination_port_range_min = resource.Body(
'destination_port_range_min', type=int
)
#: Maximum destination protocol port.
destination_port_range_max = resource.Body(
'destination_port_range_max', type=int
)
#: The source IP prefix.
source_ip_prefix = resource.Body('source_ip_prefix')
#: The destination IP prefix.
destination_ip_prefix = resource.Body('destination_ip_prefix')
#: The UUID of the source logical port.
logical_source_port = resource.Body('logical_source_port')
#: The UUID of the destination logical port.
logical_destination_port = resource.Body('logical_destination_port')
#: A dictionary of L7 parameters, in the form of
#: logical_source_network: uuid, logical_destination_network: uuid.
l7_parameters = resource.Body('l7_parameters', type=dict)
#: Summary field of a Flow Classifier, composed of the
#: protocol, source protcol port, destination ptocolo port,
#: logical_source_port, logical_destination_port and
#: l7_parameters
summary = resource.Computed('summary', default='')
project_id = resource.Body('project_id', alias='tenant_id')
#: Tenant_id (deprecated attribute).
tenant_id = resource.Body('tenant_id', deprecated=True)

View File

@ -0,0 +1,49 @@
# 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 SfcPortChain(resource.Resource):
resource_key = 'port_chain'
resources_key = 'port_chains'
base_path = '/sfc/port_chains'
# capabilities
allow_create = True
allow_fetch = True
allow_commit = True
allow_delete = True
allow_list = True
_query_mapping = resource.QueryParameters(
'description',
'name',
'project_id',
'tenant_id',
)
# Properties
#: Human-readable description for the resource.
description = resource.Body('description')
#: Human-readable name of the resource. Default is an empty string.
name = resource.Body('name')
#: List of port-pair-group UUIDs.
port_pair_groups = resource.Body('port_pair_groups', type=list)
#: List of flow-classifier UUIDs.
flow_classifiers = resource.Body('flow_classifiers', type=list)
#: A dictionary of chain parameters, correlation values can be
#: mpls and nsh, symmetric can be True or False.
chain_parameters = resource.Body('chain_parameters', type=dict)
project_id = resource.Body('project_id', alias='tenant_id')
#: Tenant_id (deprecated attribute).
tenant_id = resource.Body('tenant_id', deprecated=True)

View File

@ -0,0 +1,53 @@
# 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 SfcPortPair(resource.Resource):
resource_key = 'port_pair'
resources_key = 'port_pairs'
base_path = '/sfc/port_pairs'
# capabilities
allow_create = True
allow_fetch = True
allow_commit = True
allow_delete = True
allow_list = True
_query_mapping = resource.QueryParameters(
'description',
'name',
'egress',
'ingress',
'project_id',
'tenant_id',
)
# Properties
#: Human-readable description for the resource.
description = resource.Body('description')
#: Human-readable name of the resource. Default is an empty string.
name = resource.Body('name')
#: The UUID of the ingress Neutron port.
ingress = resource.Body('ingress')
#: The UUID of the egress Neutron port.
egress = resource.Body('egress')
#: A dictionary of service function parameters, correlation values can be
#: mpls and nsh, weight which can be an int.
service_function_parameters = resource.Body(
'service_function_parameters', type=dict
)
project_id = resource.Body('project_id', alias='tenant_id')
#: Tenant_id (deprecated attribute).
tenant_id = resource.Body('tenant_id', deprecated=True)

View File

@ -0,0 +1,57 @@
# 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 SfcPortPairGroup(resource.Resource):
resource_key = 'port_pair_group'
resources_key = 'port_pair_groups'
base_path = '/sfc/port_pair_groups'
# capabilities
allow_create = True
allow_fetch = True
allow_commit = True
allow_delete = True
allow_list = True
_query_mapping = resource.QueryParameters(
'description',
'name',
'project_id',
'tenant_id',
)
# Properties
#: Human-readable description for the resource.
description = resource.Body('description')
#: Human-readable name of the resource. Default is an empty string.
name = resource.Body('name')
#: List of port-pair UUIDs.
port_pairs = resource.Body('port_pairs', type=list)
#: Dictionary of port pair group parameters, in the form of
#: lb_fields: list of regex (eth|ip|tcp|udp)_(src|dst)),
#: ppg_n_tuple_mapping: ingress_n_tuple or egress_n_tuple.
#: The ingress or egress tuple is a dict with the following keys:
#: source_ip_prefix, destination_ip_prefix, source_port_range_min,
#: source_port_range_max, destination_port_range_min,
#: destination_port_range_max.
port_pair_group_parameters = resource.Body(
'port_pair_group_parameters', type=dict
)
#: True if passive Tap service functions support is enabled,
#: default is False.
is_tap_enabled = resource.Body('tap_enabled', type=bool)
project_id = resource.Body('project_id', alias='tenant_id')
#: Tenant_id (deprecated attribute).
tenant_id = resource.Body('tenant_id', deprecated=True)

View File

@ -0,0 +1,45 @@
# 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 SfcServiceGraph(resource.Resource):
resource_key = 'service_graph'
resources_key = 'service_graphs'
base_path = '/sfc/service_graphs'
# capabilities
allow_create = True
allow_fetch = True
allow_commit = True
allow_delete = True
allow_list = True
_query_mapping = resource.QueryParameters(
'description',
'name',
'project_id',
'tenant_id',
)
# Properties
#: Human-readable description for the resource.
description = resource.Body('description')
#: Human-readable name of the resource. Default is an empty string.
name = resource.Body('name')
#: A dictionary where the key is the source port chain and the
#: value is a list of destination port chains.
port_chains = resource.Body('port_chains')
project_id = resource.Body('project_id', alias='tenant_id')
#: Tenant_id (deprecated attribute).
tenant_id = resource.Body('tenant_id', deprecated=True)

View File

@ -0,0 +1,136 @@
# 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 sfc_flow_classifier as _flow_classifier
from openstack.network.v2 import subnet as _subnet
from openstack.tests.functional import base
class TestSFCFlowClassifier(base.BaseFunctionalTest):
FC_ID = None
def setUp(self):
super().setUp()
if not self.user_cloud.network.find_extension("sfc"):
self.skipTest("Neutron SFC Extension disabled")
self.FLOW_CLASSIFIER_NAME = 'my_classifier' + self.getUniqueString()
self.UPDATE_NAME = 'updated' + self.getUniqueString()
self.NET_NAME = 'network1' + self.getUniqueString()
self.SUBNET_NAME = 'subnet1' + self.getUniqueString()
self.PORT1_NAME = 'port1' + self.getUniqueString()
self.PORT2_NAME = 'port2' + self.getUniqueString()
self.ETHERTYPE = 'IPv4'
self.PROTOCOL = 'tcp'
self.S_PORT_RANGE_MIN = 80
self.S_PORT_RANGE_MAX = 80
self.D_PORT_RANGE_MIN = 180
self.D_PORT_RANGE_MAX = 180
self.CIDR = "10.101.0.0/24"
self.SOURCE_IP = '10.101.1.12/32'
self.DESTINATION_IP = '10.102.2.12/32'
self.PORT_CHAIN_NAME = 'my_chain' + self.getUniqueString()
self.PORT_PAIR_NAME = 'my_port_pair' + self.getUniqueString()
self.PORT_PAIR_GROUP_NAME = (
'my_port_pair_group' + self.getUniqueString()
)
self.SERVICE_GRAPH_NAME = 'my_service_graph' + self.getUniqueString()
self.op_net_client = self.operator_cloud.network
net = self.op_net_client.create_network(name=self.NET_NAME)
self.assertIsInstance(net, _network.Network)
self.NETWORK = net
subnet = self.operator_cloud.network.create_subnet(
name=self.SUBNET_NAME,
ip_version=4,
network_id=self.NETWORK.id,
cidr=self.CIDR,
)
self.assertIsInstance(subnet, _subnet.Subnet)
self.SUBNET = subnet
self.PORT1 = self._create_port(
network=self.NETWORK, port_name=self.PORT1_NAME
)
self.PORT2 = self._create_port(
network=self.NETWORK, port_name=self.PORT2_NAME
)
flow_cls = self.op_net_client.create_sfc_flow_classifier(
name=self.FLOW_CLASSIFIER_NAME,
ethertype=self.ETHERTYPE,
protocol=self.PROTOCOL,
source_port_range_min=self.S_PORT_RANGE_MIN,
source_port_range_max=self.S_PORT_RANGE_MAX,
destination_port_range_min=self.D_PORT_RANGE_MIN,
destination_port_range_max=self.D_PORT_RANGE_MAX,
source_ip_prefix=self.SOURCE_IP,
destination_ip_prefix=self.DESTINATION_IP,
logical_source_port=self.PORT1.id,
logical_destination_port=self.PORT2.id,
)
self.assertIsInstance(flow_cls, _flow_classifier.SfcFlowClassifier)
self.FLOW_CLASSIFIER = flow_cls
self.FC_ID = flow_cls.id
def _create_port(self, network, port_name):
port = self.op_net_client.create_port(
name=port_name,
network_id=network.id,
)
self.assertIsInstance(port, _port.Port)
return port
def tearDown(self):
sot = self.operator_cloud.network.delete_sfc_flow_classifier(
self.FLOW_CLASSIFIER.id, ignore_missing=True
)
self.assertIsNone(sot)
sot = self.operator_cloud.network.delete_port(self.PORT1.id)
self.assertIsNone(sot)
sot = self.operator_cloud.network.delete_port(self.PORT2.id)
self.assertIsNone(sot)
sot = self.operator_cloud.network.delete_subnet(self.SUBNET.id)
self.assertIsNone(sot)
sot = self.operator_cloud.network.delete_network(self.NETWORK.id)
self.assertIsNone(sot)
super().tearDown()
def test_sfc_flow_classifier(self):
sot = self.operator_cloud.network.find_sfc_flow_classifier(
self.FLOW_CLASSIFIER.name
)
self.assertEqual(self.ETHERTYPE, sot.ethertype)
self.assertEqual(self.SOURCE_IP, sot.source_ip_prefix)
self.assertEqual(self.PROTOCOL, sot.protocol)
classifiers = [
fc.name
for fc in self.operator_cloud.network.sfc_flow_classifiers()
]
self.assertIn(self.FLOW_CLASSIFIER_NAME, classifiers)
classifier = self.operator_cloud.network.get_sfc_flow_classifier(
self.FC_ID
)
self.assertEqual(self.FLOW_CLASSIFIER_NAME, classifier.name)
self.assertEqual(self.FC_ID, classifier.id)
classifier = self.operator_cloud.network.update_sfc_flow_classifier(
self.FC_ID, name=self.UPDATE_NAME
)
self.assertEqual(self.UPDATE_NAME, classifier.name)

View File

@ -0,0 +1,102 @@
# 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 sfc_flow_classifier
from openstack.tests.unit import base
IDENTIFIER = 'IDENTIFIER'
EXAMPLE = {
"description": "",
"project_id": "4ad57e7ce0b24fca8f12b9834d91079d",
"tenant_id": "4ad57e7ce0b24fca8f12b9834d91079d",
"ethertype": "IPv4",
"protocol": 6,
"source_port_range_min": 22,
"source_port_range_max": 2000,
"destination_port_range_min": 80,
"destination_port_range_max": 80,
"source_ip_prefix": None,
"destination_ip_prefix": "22.12.34.45",
"logical_source_port": "uuid1",
"logical_destination_port": "uuid2",
"l7_parameters": None,
"id": "6ecd9cf3-ca64-46c7-863f-f2eb1b9e838a",
"name": "flow_classifier",
}
class TestFlowClassifier(base.TestCase):
def test_basic(self):
sot = sfc_flow_classifier.SfcFlowClassifier()
self.assertEqual('flow_classifier', sot.resource_key)
self.assertEqual('flow_classifiers', sot.resources_key)
self.assertEqual('/sfc/flow_classifiers', 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 = sfc_flow_classifier.SfcFlowClassifier(**EXAMPLE)
self.assertEqual(EXAMPLE['description'], sot.description)
self.assertEqual(EXAMPLE['protocol'], sot.protocol)
self.assertEqual(EXAMPLE['ethertype'], sot.ethertype)
self.assertEqual(
EXAMPLE['source_port_range_min'], sot.source_port_range_min
)
self.assertEqual(
EXAMPLE['source_port_range_max'], sot.source_port_range_max
)
self.assertEqual(
EXAMPLE['destination_port_range_min'],
sot.destination_port_range_min,
)
self.assertEqual(
EXAMPLE['destination_port_range_max'],
sot.destination_port_range_max,
)
self.assertEqual(EXAMPLE['source_ip_prefix'], sot.source_ip_prefix)
self.assertEqual(
EXAMPLE['destination_ip_prefix'], sot.destination_ip_prefix
)
self.assertEqual(
EXAMPLE['logical_source_port'], sot.logical_source_port
)
self.assertEqual(
EXAMPLE['logical_destination_port'], sot.logical_destination_port
)
self.assertEqual(EXAMPLE['l7_parameters'], sot.l7_parameters)
self.assertEqual(EXAMPLE['id'], sot.id)
self.assertEqual(EXAMPLE['name'], sot.name)
self.assertEqual(EXAMPLE['project_id'], sot.project_id)
self.assertDictEqual(
{
"limit": "limit",
"marker": "marker",
'description': 'description',
'name': 'name',
'project_id': 'project_id',
'tenant_id': 'tenant_id',
'ethertype': 'ethertype',
'protocol': 'protocol',
'source_port_range_min': 'source_port_range_min',
'source_port_range_max': 'source_port_range_max',
'destination_port_range_min': 'destination_port_range_min',
'destination_port_range_max': 'destination_port_range_max',
'logical_source_port': 'logical_source_port',
'logical_destination_port': 'logical_destination_port',
},
sot._query_mapping._mapping,
)

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 sfc_port_chain
from openstack.tests.unit import base
IDENTIFIER = 'IDENTIFIER'
EXAMPLE = {
"description": "",
"project_id": "4ad57e7ce0b24fca8f12b9834d91079d",
"tenant_id": "4ad57e7ce0b24fca8f12b9834d91079d",
"port_pair_groups": ["p_group1", "p_group2"],
"flow_classifiers": ["f_classifier1", "f_classifier_2"],
"chain_parameters": {"correlation": "mpls", "symmetric": True},
"id": "6ecd9cf3-ca64-46c7-863f-f2eb1b9e838a",
"name": "peers",
}
class TestPortChain(base.TestCase):
def test_basic(self):
sot = sfc_port_chain.SfcPortChain()
self.assertEqual('port_chain', sot.resource_key)
self.assertEqual('port_chains', sot.resources_key)
self.assertEqual('/sfc/port_chains', 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 = sfc_port_chain.SfcPortChain(**EXAMPLE)
self.assertEqual(EXAMPLE['description'], sot.description)
self.assertEqual(EXAMPLE['port_pair_groups'], sot.port_pair_groups)
self.assertEqual(EXAMPLE['flow_classifiers'], sot.flow_classifiers)
self.assertEqual(EXAMPLE['chain_parameters'], sot.chain_parameters)
self.assertEqual(EXAMPLE['id'], sot.id)
self.assertEqual(EXAMPLE['name'], sot.name)
self.assertEqual(EXAMPLE['project_id'], sot.project_id)
self.assertDictEqual(
{
"limit": "limit",
"marker": "marker",
'description': 'description',
'name': 'name',
'project_id': 'project_id',
'tenant_id': 'tenant_id',
},
sot._query_mapping._mapping,
)

View File

@ -0,0 +1,67 @@
# 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 sfc_port_pair
from openstack.tests.unit import base
IDENTIFIER = 'IDENTIFIER'
EXAMPLE = {
"description": "",
"project_id": "4ad57e7ce0b24fca8f12b9834d91079d",
"tenant_id": "4ad57e7ce0b24fca8f12b9834d91079d",
"egress": "d294f042-1736-11ee-821a-7f8301c71f83",
"ingress": "d9908eba-1736-11ee-b77f-1fcc4c520068",
"service_function_parameters": {"correlation": "mpls", "weigjt": 101},
"id": "6ecd9cf3-ca64-46c7-863f-f2eb1b9e838a",
"name": "port_pair_1",
}
class TestSfcPortPair(base.TestCase):
def test_basic(self):
sot = sfc_port_pair.SfcPortPair()
self.assertEqual('port_pair', sot.resource_key)
self.assertEqual('port_pairs', sot.resources_key)
self.assertEqual('/sfc/port_pairs', 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 = sfc_port_pair.SfcPortPair(**EXAMPLE)
self.assertEqual(EXAMPLE['description'], sot.description)
self.assertEqual(EXAMPLE['egress'], sot.egress)
self.assertEqual(EXAMPLE['ingress'], sot.ingress)
self.assertEqual(
EXAMPLE['service_function_parameters'],
sot.service_function_parameters,
)
self.assertEqual(EXAMPLE['id'], sot.id)
self.assertEqual(EXAMPLE['name'], sot.name)
self.assertEqual(EXAMPLE['project_id'], sot.project_id)
self.assertDictEqual(
{
"limit": "limit",
"marker": "marker",
'description': 'description',
'name': 'name',
'project_id': 'project_id',
'tenant_id': 'tenant_id',
'ingress': 'ingress',
'egress': 'egress',
},
sot._query_mapping._mapping,
)

View File

@ -0,0 +1,63 @@
# 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 sfc_port_pair_group
from openstack.tests.unit import base
IDENTIFIER = 'IDENTIFIER'
EXAMPLE = {
"description": "",
"project_id": "4ad57e7ce0b24fca8f12b9834d91079d",
"tenant_id": "4ad57e7ce0b24fca8f12b9834d91079d",
"port_pairs": ["8d57819a-174d-11ee-97b0-2f370d29c014"],
"port_pair_group_parameters": {},
"id": "6ecd9cf3-ca64-46c7-863f-f2eb1b9e838a",
"name": "port_pair_gr",
}
class TestSfcPortPairGroup(base.TestCase):
def test_basic(self):
sot = sfc_port_pair_group.SfcPortPairGroup()
self.assertEqual('port_pair_group', sot.resource_key)
self.assertEqual('port_pair_groups', sot.resources_key)
self.assertEqual('/sfc/port_pair_groups', 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 = sfc_port_pair_group.SfcPortPairGroup(**EXAMPLE)
self.assertEqual(EXAMPLE['description'], sot.description)
self.assertEqual(EXAMPLE['port_pairs'], sot.port_pairs)
self.assertEqual(EXAMPLE['id'], sot.id)
self.assertEqual(
EXAMPLE['port_pair_group_parameters'],
sot.port_pair_group_parameters,
)
self.assertEqual(EXAMPLE['name'], sot.name)
self.assertEqual(EXAMPLE['project_id'], sot.project_id)
self.assertDictEqual(
{
"limit": "limit",
"marker": "marker",
'description': 'description',
'name': 'name',
'project_id': 'project_id',
'tenant_id': 'tenant_id',
},
sot._query_mapping._mapping,
)

View File

@ -0,0 +1,65 @@
# 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 sfc_service_graph
from openstack.tests.unit import base
IDENTIFIER = 'IDENTIFIER'
EXAMPLE = {
"description": "",
"project_id": "4ad57e7ce0b24fca8f12b9834d91079d",
"tenant_id": "4ad57e7ce0b24fca8f12b9834d91079d",
"port_chains": {
"0e6b9678-19aa-11ee-97ae-a3cec2c2ac72": [
"1e19c266-19aa-11ee-8e02-6fa0c9a9832d"
],
"2a394dc8-19aa-11ee-b87e-7f24d71926f1": [
"3299fcf6-19aa-11ee-9398-3f8c68c11209"
],
},
"id": "6ecd9cf3-ca64-46c7-863f-f2eb1b9e838a",
"name": "service_graph",
}
class TestSfcServiceGraph(base.TestCase):
def test_basic(self):
sot = sfc_service_graph.SfcServiceGraph()
self.assertEqual('service_graph', sot.resource_key)
self.assertEqual('service_graphs', sot.resources_key)
self.assertEqual('/sfc/service_graphs', 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 = sfc_service_graph.SfcServiceGraph(**EXAMPLE)
self.assertEqual(EXAMPLE['description'], sot.description)
self.assertEqual(EXAMPLE['port_chains'], sot.port_chains)
self.assertEqual(EXAMPLE['id'], sot.id)
self.assertEqual(EXAMPLE['name'], sot.name)
self.assertEqual(EXAMPLE['project_id'], sot.project_id)
self.assertDictEqual(
{
"limit": "limit",
"marker": "marker",
'description': 'description',
'name': 'name',
'project_id': 'project_id',
'tenant_id': 'tenant_id',
},
sot._query_mapping._mapping,
)

View File

@ -0,0 +1,6 @@
---
features:
- |
Add SFC resources: FlowClassifier, PortChain, PortPair, PortPairGroup
and ServiceGraph resources and introduce support for CRUD operations
for these.