Merge "Log server console output during create/get timestamp"
diff --git a/tempest/api/compute/admin/test_aggregates.py b/tempest/api/compute/admin/test_aggregates.py
index 57d3983..d8faa33 100644
--- a/tempest/api/compute/admin/test_aggregates.py
+++ b/tempest/api/compute/admin/test_aggregates.py
@@ -48,11 +48,11 @@
                       if (hyper['hypervisor_type'] ==
                           CONF.compute.hypervisor_type)]
 
-        hosts_available = [hyper['service']['host'] for hyper in hypers
-                           if (hyper['state'] == 'up' and
-                               hyper['status'] == 'enabled')]
-        if hosts_available:
-            cls.host = hosts_available[0]
+        cls.hosts_available = [hyper['service']['host'] for hyper in hypers
+                               if (hyper['state'] == 'up' and
+                                   hyper['status'] == 'enabled')]
+        if cls.hosts_available:
+            cls.host = cls.hosts_available[0]
         else:
             msg = "no available compute node found"
             if CONF.compute.hypervisor_type:
@@ -206,11 +206,23 @@
         az_name = data_utils.rand_name(self.az_name_prefix)
         aggregate = self._create_test_aggregate(availability_zone=az_name)
 
-        self.client.add_host(aggregate['id'], host=self.host)
-        self.addCleanup(self.client.remove_host, aggregate['id'],
-                        host=self.host)
+        # Find a host that has not been added to other zone,
+        # for one host can't be added to different zones.
+        aggregates = self.client.list_aggregates()['aggregates']
+        hosts_in_zone = []
+        for v in aggregates:
+            if v['availability_zone']:
+                hosts_in_zone.extend(v['hosts'])
+        hosts = [v for v in self.hosts_available if v not in hosts_in_zone]
+        if not hosts:
+            raise self.skipException("All hosts are already in other zones, "
+                                     "so can't add host to aggregate.")
+        host = hosts[0]
+
+        self.client.add_host(aggregate['id'], host=host)
+        self.addCleanup(self.client.remove_host, aggregate['id'], host=host)
         admin_servers_client = self.os_admin.servers_client
         server = self.create_test_server(availability_zone=az_name,
                                          wait_until='ACTIVE')
         body = admin_servers_client.show_server(server['id'])['server']
-        self.assertEqual(self.host, body['OS-EXT-SRV-ATTR:host'])
+        self.assertEqual(host, body['OS-EXT-SRV-ATTR:host'])
diff --git a/tempest/api/compute/admin/test_networks.py b/tempest/api/compute/admin/test_networks.py
index 87ce39d..99907a8 100644
--- a/tempest/api/compute/admin/test_networks.py
+++ b/tempest/api/compute/admin/test_networks.py
@@ -26,6 +26,7 @@
     API docs:
     https://developer.openstack.org/api-ref/compute/#networks-os-networks-deprecated
     """
+    max_microversion = '2.35'
 
     @classmethod
     def setup_clients(cls):
diff --git a/tempest/api/compute/test_networks.py b/tempest/api/compute/test_networks.py
index b8c79d7..76131e2 100644
--- a/tempest/api/compute/test_networks.py
+++ b/tempest/api/compute/test_networks.py
@@ -20,6 +20,8 @@
 
 
 class ComputeNetworksTest(base.BaseV2ComputeTest):
+    max_microversion = '2.35'
+
     @classmethod
     def skip_checks(cls):
         super(ComputeNetworksTest, cls).skip_checks()
diff --git a/tempest/lib/api_schema/response/compute/v2_47/servers.py b/tempest/lib/api_schema/response/compute/v2_47/servers.py
index 5d6d4c3..5922f76 100644
--- a/tempest/lib/api_schema/response/compute/v2_47/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_47/servers.py
@@ -53,3 +53,14 @@
     servers226.rebuild_server_with_admin_pass)
 rebuild_server_with_admin_pass['response_body']['properties']['server'][
     'properties'].update({'flavor': flavor})
+
+# NOTE(zhufl): Below are the unchanged schema in this microversion. We need
+# to keep this schema in this file to have the generic way to select the
+# right schema based on self.schema_versions_info mapping in service client.
+# ****** Schemas unchanged since microversion 2.26 ***
+list_tags = copy.deepcopy(servers226.list_tags)
+update_all_tags = copy.deepcopy(servers226.update_all_tags)
+delete_all_tags = copy.deepcopy(servers226.delete_all_tags)
+check_tag_existence = copy.deepcopy(servers226.check_tag_existence)
+update_tag = copy.deepcopy(servers226.update_tag)
+delete_tag = copy.deepcopy(servers226.delete_tag)
diff --git a/tempest/lib/api_schema/response/compute/v2_48/servers.py b/tempest/lib/api_schema/response/compute/v2_48/servers.py
index 5904758..02b00d6 100644
--- a/tempest/lib/api_schema/response/compute/v2_48/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_48/servers.py
@@ -113,3 +113,14 @@
 }
 
 get_server = copy.deepcopy(servers247.get_server)
+
+# NOTE(zhufl): Below are the unchanged schema in this microversion. We need
+# to keep this schema in this file to have the generic way to select the
+# right schema based on self.schema_versions_info mapping in service client.
+# ****** Schemas unchanged since microversion 2.26 ***
+list_tags = copy.deepcopy(servers247.list_tags)
+update_all_tags = copy.deepcopy(servers247.update_all_tags)
+delete_all_tags = copy.deepcopy(servers247.delete_all_tags)
+check_tag_existence = copy.deepcopy(servers247.check_tag_existence)
+update_tag = copy.deepcopy(servers247.update_tag)
+delete_tag = copy.deepcopy(servers247.delete_tag)
diff --git a/tempest/lib/api_schema/response/compute/v2_54/servers.py b/tempest/lib/api_schema/response/compute/v2_54/servers.py
index c084696..e264186 100644
--- a/tempest/lib/api_schema/response/compute/v2_54/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_54/servers.py
@@ -39,11 +39,18 @@
 rebuild_server_with_admin_pass['response_body']['properties']['server'][
     'required'].append('key_name')
 
-# ****** Schemas unchanged in microversion 2.54 since microversion 2.47 ***
-
 # NOTE(gmann): Below are the unchanged schema in this microversion. We need
 # to keep this schema in this file to have the generic way to select the
 # right schema based on self.schema_versions_info mapping in service client.
+# ****** Schemas unchanged in microversion 2.54 since microversion 2.47 ***
 get_server = copy.deepcopy(servers247.get_server)
 list_servers_detail = copy.deepcopy(servers247.list_servers_detail)
 update_server = copy.deepcopy(servers247.update_server)
+
+# ****** Schemas unchanged since microversion 2.26 ***
+list_tags = copy.deepcopy(servers247.list_tags)
+update_all_tags = copy.deepcopy(servers247.update_all_tags)
+delete_all_tags = copy.deepcopy(servers247.delete_all_tags)
+check_tag_existence = copy.deepcopy(servers247.check_tag_existence)
+update_tag = copy.deepcopy(servers247.update_tag)
+delete_tag = copy.deepcopy(servers247.delete_tag)
diff --git a/tempest/lib/api_schema/response/compute/v2_57/servers.py b/tempest/lib/api_schema/response/compute/v2_57/servers.py
index ed1ca7d..d7de5fd 100644
--- a/tempest/lib/api_schema/response/compute/v2_57/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_57/servers.py
@@ -43,11 +43,18 @@
 rebuild_server_with_admin_pass['response_body']['properties']['server'][
     'required'].append('user_data')
 
-# ****** Schemas unchanged in microversion 2.57 since microversion 2.54 ***
-
 # NOTE(gmann): Below are the unchanged schema in this microversion. We need
-# to keeo this schema in this file to have the generic way to select the
+# to keep this schema in this file to have the generic way to select the
 # right schema based on self.schema_versions_info mapping in service client.
+# ****** Schemas unchanged in microversion 2.57 since microversion 2.54 ***
 get_server = copy.deepcopy(servers254.get_server)
 list_servers_detail = copy.deepcopy(servers254.list_servers_detail)
 update_server = copy.deepcopy(servers254.update_server)
+
+# ****** Schemas unchanged since microversion 2.26 ***
+list_tags = copy.deepcopy(servers254.list_tags)
+update_all_tags = copy.deepcopy(servers254.update_all_tags)
+delete_all_tags = copy.deepcopy(servers254.delete_all_tags)
+check_tag_existence = copy.deepcopy(servers254.check_tag_existence)
+update_tag = copy.deepcopy(servers254.update_tag)
+delete_tag = copy.deepcopy(servers254.delete_tag)
diff --git a/tempest/lib/api_schema/response/compute/v2_63/servers.py b/tempest/lib/api_schema/response/compute/v2_63/servers.py
index 5cdaf54..6a20890 100644
--- a/tempest/lib/api_schema/response/compute/v2_63/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_63/servers.py
@@ -63,3 +63,14 @@
     'properties'].update({'trusted_image_certificates': trusted_certs})
 get_server['response_body']['properties']['server'][
     'required'].append('trusted_image_certificates')
+
+# NOTE(zhufl): Below are the unchanged schema in this microversion. We need
+# to keep this schema in this file to have the generic way to select the
+# right schema based on self.schema_versions_info mapping in service client.
+# ****** Schemas unchanged since microversion 2.26 ***
+list_tags = copy.deepcopy(servers257.list_tags)
+update_all_tags = copy.deepcopy(servers257.update_all_tags)
+delete_all_tags = copy.deepcopy(servers257.delete_all_tags)
+check_tag_existence = copy.deepcopy(servers257.check_tag_existence)
+update_tag = copy.deepcopy(servers257.update_tag)
+delete_tag = copy.deepcopy(servers257.delete_tag)
diff --git a/tempest/lib/services/image/v2/images_client.py b/tempest/lib/services/image/v2/images_client.py
index ed6df47..3c38dba 100644
--- a/tempest/lib/services/image/v2/images_client.py
+++ b/tempest/lib/services/image/v2/images_client.py
@@ -32,7 +32,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        http://developer.openstack.org/api-ref/image/v2/index.html#update-an-image
+        https://developer.openstack.org/api-ref/image/v2/#update-image
         """
         data = json.dumps(patch)
         headers = {"Content-Type": "application/openstack-images-v2.0"
@@ -47,7 +47,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        http://developer.openstack.org/api-ref/image/v2/index.html#create-an-image
+        https://developer.openstack.org/api-ref/image/v2/#create-image
         """
         data = json.dumps(kwargs)
         resp, body = self.post('images', data)
@@ -84,7 +84,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        http://developer.openstack.org/api-ref/image/v2/#delete-an-image
+        https://developer.openstack.org/api-ref/image/v2/#delete-image
          """
         url = 'images/%s' % image_id
         resp, _ = self.delete(url)
@@ -96,7 +96,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        http://developer.openstack.org/api-ref/image/v2/#show-images
+        https://developer.openstack.org/api-ref/image/v2/#list-images
         """
         url = 'images'
 
@@ -113,7 +113,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        http://developer.openstack.org/api-ref/image/v2/#show-image-details
+        https://developer.openstack.org/api-ref/image/v2/#show-image
         """
         url = 'images/%s' % image_id
         resp, body = self.get(url)