Create floating IPs with additional parameters.

It adds missing parameters to create_floatingip method:
  - port: is translated to port_id=port['id']
  - client: is used to create/delete returned floating IP
  - **kwargs: are forwarded as they are to client

It deletes floating IPs on final cleanup even when created
  by other client than default one.

It implements delete_floatingip method.

Change-Id: Ie2421839947f9010e8d2590cde1fd86669092fb9
diff --git a/neutron_tempest_plugin/api/base.py b/neutron_tempest_plugin/api/base.py
index 966b30d..8ec98cd 100644
--- a/neutron_tempest_plugin/api/base.py
+++ b/neutron_tempest_plugin/api/base.py
@@ -63,6 +63,8 @@
     # Derive from BaseAdminNetworkTest class to have this initialized
     admin_client = None
 
+    external_network_id = CONF.network.public_network_id
+
     @classmethod
     def get_client_manager(cls, credential_type=None, roles=None,
                            force_new=None):
@@ -139,8 +141,8 @@
 
             # Clean up floating IPs
             for floating_ip in cls.floating_ips:
-                cls._try_delete_resource(cls.client.delete_floatingip,
-                                         floating_ip['id'])
+                cls._try_delete_resource(cls.delete_floatingip, floating_ip)
+
             # Clean up routers
             for router in cls.routers:
                 cls._try_delete_resource(cls.delete_router,
@@ -577,15 +579,56 @@
                                               *args, **kwargs)
 
     @classmethod
-    def create_floatingip(cls, external_network_id):
-        """Wrapper utility that returns a test floating IP."""
-        body = cls.client.create_floatingip(
-            floating_network_id=external_network_id)
-        fip = body['floatingip']
+    def create_floatingip(cls, external_network_id=None, port=None,
+                          client=None, **kwargs):
+        """Creates a floating IP.
+
+        Create a floating IP and schedule it for later deletion.
+        If a client is passed, then it is used for deleting the IP too.
+
+        :param external_network_id: network ID where to create
+        By default this is 'CONF.network.public_network_id'.
+
+        :param port: port to bind floating IP to
+        This is translated to 'port_id=port['id']'
+        By default it is None.
+
+        :param client: network client to be used for creating and cleaning up
+        the floating IP.
+
+        :param **kwargs: additional creation parameters to be forwarded to
+        networking server.
+        """
+
+        client = client or cls.client
+        external_network_id = (external_network_id or
+                               cls.external_network_id)
+
+        if port:
+            kwargs['port_id'] = port['id']
+
+        fip = client.create_floatingip(external_network_id,
+                                       **kwargs)['floatingip']
+
+        # save client to be used later in cls.delete_floatingip
+        # for final cleanup
+        fip['client'] = client
         cls.floating_ips.append(fip)
         return fip
 
     @classmethod
+    def delete_floatingip(cls, floating_ip, client=None):
+        """Delete floating IP
+
+        :param client: Client to be used
+        If client is not given it will use the client used to create
+        the floating IP, or cls.client if unknown.
+        """
+
+        client = client or floating_ip.get('client') or cls.client
+        client.delete_floatingip(floating_ip['id'])
+
+    @classmethod
     def create_router_interface(cls, router_id, subnet_id):
         """Wrapper utility that returns a router interface."""
         interface = cls.client.add_router_interface_with_subnet_id(