Add tests for testing servers ips recordset

There is very important feature in Designate which allows to generate records when notification
is received from nova and/or neutron

Change-Id: I2d832a55a58c955286e63fa21a3112cb91728ea0
Related-prod: PROD-24589
diff --git a/designate_tempest_plugin/common/waiters.py b/designate_tempest_plugin/common/waiters.py
index 5c06623..e4645ea 100644
--- a/designate_tempest_plugin/common/waiters.py
+++ b/designate_tempest_plugin/common/waiters.py
@@ -149,31 +149,31 @@
             raise lib_exc.TimeoutException(message)
 
 
-def wait_for_recordset_status(client, zone_id, recordset_id, status):
+def wait_for_recordset_status(client, zone_id, recordset_id,
+                              status, headers=None):
     """Waits for a recordset to reach the given status."""
     LOG.info('Waiting for recordset %s to reach %s',
              recordset_id, status)
 
-    _, recordset = client.show_recordset(zone_id, recordset_id)
+    _, recordset = client.show_recordset(zone_id, recordset_id,
+                                         headers=headers)
     start = int(time.time())
 
     while recordset['status'] != status:
         time.sleep(client.build_interval)
-        _, recordset = client.show_recordset(zone_id, recordset_id)
+        _, recordset = client.show_recordset(zone_id, recordset_id,
+                                             headers=headers)
         status_curr = recordset['status']
         if status_curr == status:
             LOG.info('Recordset %s reached %s', recordset_id, status)
             return
 
         if int(time.time()) - start >= client.build_timeout:
-            message = ('Recordset %(recordset_id)s failed to reach '
-                       'status=%(status) within the required time '
-                       '(%(timeout)s s). Current '
-                       'status: %(status_curr)s' %
-                       {'recordset_id': recordset_id,
-                        'status': status,
-                        'status_curr': status_curr,
-                        'timeout': client.build_timeout})
+            message = ('Recordset {0} failed to reach '
+                       'status={1} within the required time '
+                       '({2} s). Current status: {3}'.
+                       format(recordset_id, status,
+                              client.build_timeout, status_curr))
 
             caller = test_utils.find_test_caller()
 
diff --git a/designate_tempest_plugin/config.py b/designate_tempest_plugin/config.py
index c82421a..91e326d 100644
--- a/designate_tempest_plugin/config.py
+++ b/designate_tempest_plugin/config.py
@@ -49,7 +49,9 @@
     cfg.IntOpt('query_timeout',
                default=1,
                help="The timeout on a single dns query to a nameserver"),
-
+    cfg.StrOpt('zone_id',
+               help="The target zone to test the dns recordsets "
+                    "If it is not specified, a new zone will be created ")
 ]
 
 dns_feature_group = cfg.OptGroup(name='dns_feature_enabled',
@@ -82,4 +84,11 @@
                 default=False,
                 help="Is https://bugs.launchpad.net/designate/+bug/1573141 "
                 "fixed"),
+    cfg.BoolOpt('notification_nova_fixed',
+                default=False,
+                help="Is the notification handlers for nova_fixed enabled."),
+    cfg.BoolOpt('notification_neutron_floatingip',
+                default=False,
+                help="Is the notification handlers for neutron_floatingip "
+                "enabled."),
 ]
diff --git a/designate_tempest_plugin/services/dns/json/base.py b/designate_tempest_plugin/services/dns/json/base.py
index d7bf614..13de955 100644
--- a/designate_tempest_plugin/services/dns/json/base.py
+++ b/designate_tempest_plugin/services/dns/json/base.py
@@ -152,16 +152,17 @@
 
         return resp, self.deserialize(resp, body)
 
-    def _list_request(self, resource, params=None):
+    def _list_request(self, resource, headers=None, params=None):
         """Gets a list of objects.
         :param resource: The name of the REST resource, e.g., 'zones'.
+        :param headers (dict): The headers to use for the request.
         :param params: A Python dict that represents the query paramaters to
                        include in the request URI.
         :returns: Serialized object as a dictionary.
         """
         uri = self.get_uri(resource, params=params)
 
-        resp, body = self.get(uri)
+        resp, body = self.get(uri, headers=headers)
 
         self.expected_success(self.LIST_STATUS_CODES, resp.status)
 
diff --git a/designate_tempest_plugin/services/dns/v2/json/recordset_client.py b/designate_tempest_plugin/services/dns/v2/json/recordset_client.py
index 578ccf3..f52b7c3 100644
--- a/designate_tempest_plugin/services/dns/v2/json/recordset_client.py
+++ b/designate_tempest_plugin/services/dns/v2/json/recordset_client.py
@@ -67,18 +67,20 @@
         return resp, body
 
     @base.handle_errors
-    def show_recordset(self, zone_uuid, recordset_uuid, params=None):
+    def show_recordset(self, zone_uuid, recordset_uuid,
+                       headers=None, params=None):
         """Gets a specific recordset related to a specific zone.
         :param zone_uuid: Unique identifier of the zone in UUID format.
         :param recordset_uuid: Unique identifier of the recordset in
                                UUID format.
+        :param headers (dict): The headers to use for the request.
         :param params: A Python dict that represents the query paramaters to
                        include in the request URI.
         :return: Serialized recordset as a list.
         """
         return self._show_request(
             'zones/{0}/recordsets'.format(zone_uuid), recordset_uuid,
-            params=params)
+            headers=headers, params=params)
 
     @base.handle_errors
     def delete_recordset(self, zone_uuid, recordset_uuid, params=None):
@@ -99,15 +101,17 @@
         return resp, body
 
     @base.handle_errors
-    def list_recordset(self, uuid, params=None):
+    def list_recordset(self, uuid, headers=None, params=None):
         """List recordsets related to the specified zone.
         :param uuid: Unique identifier of the zone in UUID format.
+        :param headers (dict): The headers to use for the request.
         :param params: A Python dict that represents the query paramaters to
                        include in the request URI.
         :return: Serialized recordset as a list.
         """
         return self._list_request(
-            'zones/{0}/recordsets'.format(uuid), params=params)
+            'zones/{0}/recordsets'.format(uuid),
+            headers=headers, params=params)
 
     @base.handle_errors
     def show_zones_recordset(self, recordset_uuid, params=None):
diff --git a/designate_tempest_plugin/services/dns/v2/json/zones_client.py b/designate_tempest_plugin/services/dns/v2/json/zones_client.py
index ac360e6..8471719 100644
--- a/designate_tempest_plugin/services/dns/v2/json/zones_client.py
+++ b/designate_tempest_plugin/services/dns/v2/json/zones_client.py
@@ -57,23 +57,26 @@
         return resp, body
 
     @base.handle_errors
-    def show_zone(self, uuid, params=None):
+    def show_zone(self, uuid, headers=None, params=None):
         """Gets a specific zone.
         :param uuid: Unique identifier of the zone in UUID format.
+        :param headers (dict): The headers to use for the request.
         :param params: A Python dict that represents the query paramaters to
                        include in the request URI.
         :return: Serialized zone as a dictionary.
         """
-        return self._show_request('zones', uuid, params=params)
+        return self._show_request('zones', uuid,
+                                  headers=headers, params=params)
 
     @base.handle_errors
-    def list_zones(self, params=None):
+    def list_zones(self, headers=None, params=None):
         """Gets a list of zones.
+        :param headers (dict): The headers to use for the request.
         :param params: A Python dict that represents the query paramaters to
                        include in the request URI.
         :return: Serialized zones as a list.
         """
-        return self._list_request('zones', params=params)
+        return self._list_request('zones', headers=headers, params=params)
 
     @base.handle_errors
     def delete_zone(self, uuid, params=None):
diff --git a/designate_tempest_plugin/tests/scenario/v2/designate_manager.py b/designate_tempest_plugin/tests/scenario/v2/designate_manager.py
new file mode 100644
index 0000000..77f0796
--- /dev/null
+++ b/designate_tempest_plugin/tests/scenario/v2/designate_manager.py
@@ -0,0 +1,39 @@
+# 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 tempest.scenario import manager
+
+
+class DesignateScenarioTest(manager.ScenarioTest):
+
+    credentials = ['primary', 'admin']
+    headers = {'x-auth-all-projects': 'True'}
+
+    @classmethod
+    def setup_clients(cls):
+        super(DesignateScenarioTest, cls).setup_clients()
+        os_adm = getattr(cls, 'os_{}'.format(cls.credentials[1]))
+        cls.zone_client = os_adm.dns_v2.ZonesClient(service='dns')
+        cls.recordset_client = os_adm.dns_v2.RecordsetClient(service='dns')
+
+    def get_zone_name_by_uuid(self, zone_id):
+        _, zones = self.zone_client.list_zones(headers=self.headers)
+        for zone in zones['zones']:
+            if zone.get('id') == zone_id:
+                return zone.get('name')
+
+    def get_recordset_by_name(self, zone_id, recordset_name):
+        _, recordsets = self.recordset_client.list_recordset(
+            zone_id, headers=self.headers)
+        for recordset in recordsets['recordsets']:
+            if recordset.get('name') == recordset_name:
+                return recordset
diff --git a/designate_tempest_plugin/tests/scenario/v2/test_server_ips_recordset.py b/designate_tempest_plugin/tests/scenario/v2/test_server_ips_recordset.py
new file mode 100644
index 0000000..6b41008
--- /dev/null
+++ b/designate_tempest_plugin/tests/scenario/v2/test_server_ips_recordset.py
@@ -0,0 +1,79 @@
+# 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.
+
+import testtools
+
+from designate_tempest_plugin.common import waiters
+from designate_tempest_plugin.tests.scenario.v2 import designate_manager \
+    as manager
+from tempest import config
+from tempest.lib import decorators
+from tempest.lib.common.utils import data_utils
+
+CONF = config.CONF
+
+
+class TestServerIpsRecordset(manager.DesignateScenarioTest):
+
+    build_timeout = CONF.dns.build_timeout
+
+    @classmethod
+    def skip_checks(cls):
+        super(TestServerIpsRecordset, cls).skip_checks()
+        if not CONF.dns.zone_id:
+            raise cls.skipException(
+                "Does not have zone_id")
+
+    def setUp(self):
+        super(TestServerIpsRecordset, self).setUp()
+        self.server_name = 'test-dns-server-' + data_utils.rand_name()
+        self.server = self.create_server(name=self.server_name,
+                                         wait_until='ACTIVE')
+        self.zone_id = CONF.dns.zone_id
+        self.zone_name = self.get_zone_name_by_uuid(self.zone_id)
+
+    def _get_server_fixed_ip(self, server):
+        network = self.get_tenant_network()
+        addresses = (server['addresses'][network['name']]
+                     if network else [])
+        for address in addresses:
+            if (address['version'] == CONF.validation.ip_version_for_ssh
+                    and address['OS-EXT-IPS:type'] == 'fixed'):
+                return address['addr']
+
+    @testtools.skipUnless(
+        CONF.dns_feature_enabled.notification_nova_fixed,
+        'The notification handlers for nova_fixed is disabled')
+    @decorators.idempotent_id('d23f19a2-a3c9-49cc-9a6b-3a9b6830423f')
+    def test_srever_fixed_ip_recordset(self):
+        recordset_name = self.server_name + '.' + self.zone_name
+        recordset = self.get_recordset_by_name(self.zone_id, recordset_name)
+        waiters.wait_for_recordset_status(self.recordset_client, self.zone_id,
+                                          recordset['id'], 'ACTIVE',
+                                          headers=self.headers)
+        fixed_ip = self._get_server_fixed_ip(self.server)
+        self.assertEqual(fixed_ip, recordset['records'][0])
+
+    @decorators.idempotent_id('57a7507f-e78d-4c60-877d-cd239602222c')
+    @testtools.skipUnless(
+        CONF.dns_feature_enabled.notification_neutron_floatingip,
+        'The notification handlers for neutron_floatingip is disabled')
+    def test_srever_floating_ip_recordset(self):
+        floating_ip = self.create_floating_ip(self.server)['ip']
+        recordset_floating_ip_name =\
+            floating_ip.replace('.', '-') + '.' + self.zone_name
+        recordset_floating_ip = self.get_recordset_by_name(
+            self.zone_id, recordset_floating_ip_name)
+        waiters.wait_for_recordset_status(self.recordset_client, self.zone_id,
+                                          recordset_floating_ip['id'],
+                                          'ACTIVE', headers=self.headers)
+        self.assertEqual(floating_ip, recordset_floating_ip['records'][0])