Check rescue_server action attributes of Nova APIs

This patch adds the JSON schema for Nova V2 & V3 rescue server
action APIs response and validate the response with added JSON schema
to block the backward incompatibility change in the future.

For V3 API, "admin_password" in response body is depend on config
variable "enable_instance_password". So schema and request
is adjusted accordingly.
NOTE - V2 rescue API's response does not on above config variable.

The response body of rescue server V2 APIs is below:
{
    "adminPass": "%(password)s"
}

The response body of rescue server V3 APIs is below:
If CONF.enable_instance_password is true-
{
    "admin_password": "%(password)s"
}
Else
    {}

Partially implements blueprint nova-api-attribute-test

Change-Id: I85f18eaa58bfef1871100816f97487f9fa9bc0ee
diff --git a/tempest/api_schema/compute/v2/servers.py b/tempest/api_schema/compute/v2/servers.py
index 551924a..405ebe7 100644
--- a/tempest/api_schema/compute/v2/servers.py
+++ b/tempest/api_schema/compute/v2/servers.py
@@ -281,3 +281,14 @@
     'properties'].update({'adminPass': {'type': 'string'}})
 rebuild_server_with_admin_pass['response_body']['properties']['server'][
     'required'].append('adminPass')
+
+rescue_server = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'adminPass': {'type': 'string'}
+        },
+        'required': ['adminPass']
+    }
+}
diff --git a/tempest/api_schema/compute/v3/servers.py b/tempest/api_schema/compute/v3/servers.py
index cebb2d7..5f348e0 100644
--- a/tempest/api_schema/compute/v3/servers.py
+++ b/tempest/api_schema/compute/v3/servers.py
@@ -190,3 +190,18 @@
     'properties'].update({'admin_password': {'type': 'string'}})
 rebuild_server_with_admin_pass['response_body']['properties']['server'][
     'required'].append('admin_password')
+
+rescue_server_with_admin_pass = {
+    'status_code': [202],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'admin_password': {'type': 'string'}
+        },
+        'required': ['admin_password']
+    }
+}
+
+rescue_server = copy.deepcopy(rescue_server_with_admin_pass)
+del rescue_server['response_body']['properties']
+del rescue_server['response_body']['required']
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index 05f74cd..a0ffc91 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -455,7 +455,8 @@
 
     def rescue_server(self, server_id, **kwargs):
         """Rescue the provided server."""
-        return self.action(server_id, 'rescue', 'adminPass', None, **kwargs)
+        return self.action(server_id, 'rescue', 'adminPass',
+                           schema.rescue_server, **kwargs)
 
     def unrescue_server(self, server_id):
         """Unrescue the provided server."""
diff --git a/tempest/services/compute/v3/json/servers_client.py b/tempest/services/compute/v3/json/servers_client.py
index 27e95e8..51c4499 100644
--- a/tempest/services/compute/v3/json/servers_client.py
+++ b/tempest/services/compute/v3/json/servers_client.py
@@ -450,8 +450,16 @@
 
     def rescue_server(self, server_id, **kwargs):
         """Rescue the provided server."""
-        return self.action(server_id, 'rescue', 'admin_password',
-                           None, **kwargs)
+        post_body = json.dumps({'rescue': kwargs})
+        resp, body = self.post('servers/%s/action' % str(server_id),
+                               post_body)
+        if CONF.compute_feature_enabled.enable_instance_password:
+            rescue_schema = schema.rescue_server_with_admin_pass
+        else:
+            rescue_schema = schema.rescue_server
+        body = json.loads(body)
+        self.validate_response(rescue_schema, resp, body)
+        return resp, body
 
     def unrescue_server(self, server_id):
         """Unrescue the provided server."""