From 6adda93c9d52a1bb841261725f666a439b54539c Mon Sep 17 00:00:00 2001
From: Anastasia Latynskaya <anlatynskaya@mirantis.com>
Date: Mon, 10 Jun 2013 13:08:29 +0400
Subject: [PATCH] Connectivity between the endpoint version and
 OS_VOLUME_API_VERSION.

Adds functionality which allows user to work with
that cinder API version which is the same as
the endpoint version.

Fixes: bug #1169455

Change-Id: I9bb46e602d15856d2da502a6ac2b6c25e76f4fa3
---
 cinderclient/client.py              | 11 +++++++++++
 cinderclient/exceptions.py          |  4 ++++
 cinderclient/shell.py               |  9 +++++++++
 cinderclient/tests/v1/fakes.py      |  9 +++++++++
 cinderclient/tests/v1/test_shell.py |  2 +-
 cinderclient/tests/v2/fakes.py      |  9 +++++++++
 cinderclient/v1/client.py           |  3 +++
 cinderclient/v2/client.py           |  3 +++
 8 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/cinderclient/client.py b/cinderclient/client.py
index 0cdb861c3..3b3b82848 100644
--- a/cinderclient/client.py
+++ b/cinderclient/client.py
@@ -369,6 +369,17 @@ class HTTPClient(object):
 
         return self._extract_service_catalog(url, resp, body)
 
+    def get_volume_api_version_from_endpoint(self):
+        magic_tuple = urlparse.urlsplit(self.management_url)
+        scheme, netloc, path, query, frag = magic_tuple
+        v = path.split("/")[1]
+        valid_versions = ['v1', 'v2']
+        if v not in valid_versions:
+            msg = "Invalid client version '%s'. must be one of: %s" % (
+                  (v, ', '.join(valid_versions)))
+            raise exceptions.UnsupportedVersion(msg)
+        return v[1:]
+
 
 def get_client_class(version):
     version_map = {
diff --git a/cinderclient/exceptions.py b/cinderclient/exceptions.py
index d7be18088..534888e37 100644
--- a/cinderclient/exceptions.py
+++ b/cinderclient/exceptions.py
@@ -10,6 +10,10 @@ class UnsupportedVersion(Exception):
     pass
 
 
+class InvalidAPIVersion(Exception):
+    pass
+
+
 class CommandError(Exception):
     pass
 
diff --git a/cinderclient/shell.py b/cinderclient/shell.py
index bf952987d..84f926bbf 100644
--- a/cinderclient/shell.py
+++ b/cinderclient/shell.py
@@ -448,6 +448,15 @@ class OpenStackCinderShell(object):
         except exc.AuthorizationFailure:
             raise exc.CommandError("Unable to authorize user")
 
+        endpoint_api_version = self.cs.get_volume_api_version_from_endpoint()
+        if endpoint_api_version != options.os_volume_api_version:
+            msg = (("Volume API version is set to %s "
+                    "but you are accessing a %s endpoint. "
+                    "Change its value via either --os-volume-api-version "
+                    "or env[OS_VOLUME_API_VERSION]")
+                   % (options.os_volume_api_version, endpoint_api_version))
+            raise exc.InvalidAPIVersion(msg)
+
         args.func(self.cs, args)
 
     def _run_extension_hooks(self, hook_type, *args, **kwargs):
diff --git a/cinderclient/tests/v1/fakes.py b/cinderclient/tests/v1/fakes.py
index 411c5e191..2e15f3eb8 100644
--- a/cinderclient/tests/v1/fakes.py
+++ b/cinderclient/tests/v1/fakes.py
@@ -119,6 +119,9 @@ class FakeClient(fakes.FakeClient, client.Client):
                                extensions=kwargs.get('extensions'))
         self.client = FakeHTTPClient(**kwargs)
 
+    def get_volume_api_version_from_endpoint(self):
+        return self.client.get_volume_api_version_from_endpoint()
+
 
 class FakeHTTPClient(base_client.HTTPClient):
 
@@ -127,6 +130,7 @@ class FakeHTTPClient(base_client.HTTPClient):
         self.password = 'password'
         self.auth_url = 'auth_url'
         self.callstack = []
+        self.management_url = 'http://10.0.2.15:8776/v1/fake'
 
     def _cs_request(self, url, method, **kwargs):
         # Check that certain things are called correctly
@@ -164,6 +168,11 @@ class FakeHTTPClient(base_client.HTTPClient):
         else:
             return utils.TestResponse({"status": status}), body
 
+    def get_volume_api_version_from_endpoint(self):
+        magic_tuple = urlparse.urlsplit(self.management_url)
+        scheme, netloc, path, query, frag = magic_tuple
+        return path.lstrip('/').split('/')[0][1:]
+
     #
     # Snapshots
     #
diff --git a/cinderclient/tests/v1/test_shell.py b/cinderclient/tests/v1/test_shell.py
index 9e8e2f7c0..d107ae5f7 100644
--- a/cinderclient/tests/v1/test_shell.py
+++ b/cinderclient/tests/v1/test_shell.py
@@ -32,7 +32,7 @@ class ShellTest(utils.TestCase):
         'CINDER_USERNAME': 'username',
         'CINDER_PASSWORD': 'password',
         'CINDER_PROJECT_ID': 'project_id',
-        'OS_VOLUME_API_VERSION': '1.1',
+        'OS_VOLUME_API_VERSION': '1',
         'CINDER_URL': 'http://no.where',
     }
 
diff --git a/cinderclient/tests/v2/fakes.py b/cinderclient/tests/v2/fakes.py
index f90ace363..eab1a5a23 100644
--- a/cinderclient/tests/v2/fakes.py
+++ b/cinderclient/tests/v2/fakes.py
@@ -126,6 +126,9 @@ class FakeClient(fakes.FakeClient, client.Client):
                                extensions=kwargs.get('extensions'))
         self.client = FakeHTTPClient(**kwargs)
 
+    def get_volume_api_version_from_endpoint(self):
+        return self.client.get_volume_api_version_from_endpoint()
+
 
 class FakeHTTPClient(base_client.HTTPClient):
 
@@ -134,6 +137,7 @@ class FakeHTTPClient(base_client.HTTPClient):
         self.password = 'password'
         self.auth_url = 'auth_url'
         self.callstack = []
+        self.management_url = 'http://10.0.2.15:8776/v2/fake'
 
     def _cs_request(self, url, method, **kwargs):
         # Check that certain things are called correctly
@@ -171,6 +175,11 @@ class FakeHTTPClient(base_client.HTTPClient):
         else:
             return utils.TestResponse({"status": status}), body
 
+    def get_volume_api_version_from_endpoint(self):
+        magic_tuple = urlparse.urlsplit(self.management_url)
+        scheme, netloc, path, query, frag = magic_tuple
+        return path.lstrip('/').split('/')[0][1:]
+
     #
     # Snapshots
     #
diff --git a/cinderclient/v1/client.py b/cinderclient/v1/client.py
index a5b9b0246..2906e2fa0 100644
--- a/cinderclient/v1/client.py
+++ b/cinderclient/v1/client.py
@@ -98,3 +98,6 @@ class Client(object):
         credentials are wrong.
         """
         self.client.authenticate()
+
+    def get_volume_api_version_from_endpoint(self):
+        return self.client.get_volume_api_version_from_endpoint()
diff --git a/cinderclient/v2/client.py b/cinderclient/v2/client.py
index eb2760c8e..5a8b48e53 100644
--- a/cinderclient/v2/client.py
+++ b/cinderclient/v2/client.py
@@ -95,3 +95,6 @@ class Client(object):
         credentials are wrong.
         """
         self.client.authenticate()
+
+    def get_volume_api_version_from_endpoint(self):
+        return self.client.get_volume_api_version_from_endpoint()