Add Local IP API tests
Tests were verified on OVS environment.
API job definition is not changed, because OVN does not
support Local IP.
Depends-On: https://review.opendev.org/c/openstack/neutron/+/816435
Depends-On: https://review.opendev.org/c/openstack/neutron/+/818228
Change-Id: I4760db4dd9916ec895ef63573c49bde91727d142
diff --git a/neutron_tempest_plugin/api/base.py b/neutron_tempest_plugin/api/base.py
index ecdd00a..53d95ec 100644
--- a/neutron_tempest_plugin/api/base.py
+++ b/neutron_tempest_plugin/api/base.py
@@ -118,6 +118,8 @@
cls.routers = []
cls.floating_ips = []
cls.port_forwardings = []
+ cls.local_ips = []
+ cls.local_ip_associations = []
cls.metering_labels = []
cls.service_profiles = []
cls.flavors = []
@@ -167,6 +169,15 @@
for floating_ip in cls.floating_ips:
cls._try_delete_resource(cls.delete_floatingip, floating_ip)
+ # Clean up Local IP Associations
+ for association in cls.local_ip_associations:
+ cls._try_delete_resource(cls.delete_local_ip_association,
+ association)
+ # Clean up Local IPs
+ for local_ip in cls.local_ips:
+ cls._try_delete_resource(cls.delete_local_ip,
+ local_ip)
+
# Clean up conntrack helpers
for cth in cls.conntrack_helpers:
cls._try_delete_resource(cls.delete_conntrack_helper, cth)
@@ -732,6 +743,98 @@
client = client or pf.get('client') or cls.client
client.delete_port_forwarding(pf['floatingip_id'], pf['id'])
+ def create_local_ip(cls, network_id=None,
+ client=None, **kwargs):
+ """Creates a Local IP.
+
+ Create a Local IP and schedule it for later deletion.
+ If a client is passed, then it is used for deleting the IP too.
+
+ :param network_id: network ID where to create
+ By default this is 'CONF.network.public_network_id'.
+
+ :param client: network client to be used for creating and cleaning up
+ the Local IP.
+
+ :param **kwargs: additional creation parameters to be forwarded to
+ networking server.
+ """
+
+ client = client or cls.client
+ network_id = (network_id or
+ cls.external_network_id)
+
+ local_ip = client.create_local_ip(network_id,
+ **kwargs)['local_ip']
+
+ # save client to be used later in cls.delete_local_ip
+ # for final cleanup
+ local_ip['client'] = client
+ cls.local_ips.append(local_ip)
+ return local_ip
+
+ @classmethod
+ def delete_local_ip(cls, local_ip, client=None):
+ """Delete Local IP
+
+ :param client: Client to be used
+ If client is not given it will use the client used to create
+ the Local IP, or cls.client if unknown.
+ """
+
+ client = client or local_ip.get('client') or cls.client
+ client.delete_local_ip(local_ip['id'])
+
+ @classmethod
+ def create_local_ip_association(cls, local_ip_id, fixed_port_id,
+ fixed_ip_address=None, client=None):
+ """Creates a Local IP association.
+
+ Create a Local IP Association and schedule it for later deletion.
+ If a client is passed, then it is used for deleting the association
+ too.
+
+ :param local_ip_id: The ID of the Local IP.
+
+ :param fixed_port_id: The ID of the Neutron port
+ to be associated with the Local IP
+
+ :param fixed_ip_address: The fixed IPv4 address of the Neutron
+ port to be associated with the Local IP
+
+ :param client: network client to be used for creating and cleaning up
+ the Local IP Association.
+ """
+
+ client = client or cls.client
+
+ association = client.create_local_ip_association(
+ local_ip_id, fixed_port_id,
+ fixed_ip_address)['port_association']
+
+ # save ID of Local IP for final cleanup
+ association['local_ip_id'] = local_ip_id
+
+ # save client to be used later in
+ # cls.delete_local_ip_association for final cleanup
+ association['client'] = client
+ cls.local_ip_associations.append(association)
+ return association
+
+ @classmethod
+ def delete_local_ip_association(cls, association, client=None):
+
+ """Delete Local IP Association
+
+ :param client: Client to be used
+ If client is not given it will use the client used to create
+ the local IP association, or cls.client if unknown.
+ """
+
+ client = client or association.get('client') or cls.client
+ client.delete_local_ip_association(association['local_ip_id'],
+ association['fixed_port_id'])
+
@classmethod
def create_router_interface(cls, router_id, subnet_id):
"""Wrapper utility that returns a router interface."""