summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Kurilin <akurilin@mirantis.com>2015-03-31 18:09:36 +0300
committerAndrey Kurilin <akurilin@mirantis.com>2015-04-22 15:03:07 +0300
commit61ef35fe79e2a3a76987a92f9ee2db0bf1f6e651 (patch)
tree04133ff5b6f274a2885bf499e4952f3c751df324
parent5eab1430f2a7a91e2df22405913f328c9870b2e3 (diff)
Deprecate v1.1 and remove v3
Module novaclient.v1_1 is already deprecated, so it's time to stop using it inside novaclient. Since support of v3 nova is undocumented feature, which uses v2 implementation, we can remove code related to it. Also, this patch removes redundant check for compute api version != 1.0. Change-Id: I06b349f704d5ae2c592d8d286da268870f2a69e9
Notes
Notes (review): Verified+2: Jenkins Code-Review+2: Kevin L. Mitchell <kevin.mitchell@rackspace.com> Code-Review+2: Sean Dague <sean@dague.net> Workflow+1: Sean Dague <sean@dague.net> Code-Review+1: Michal Rostecki <michal.rostecki@allegrogroup.com> Submitted-by: Jenkins Submitted-at: Mon, 27 Apr 2015 13:23:13 +0000 Reviewed-on: https://review.openstack.org/169378 Project: openstack/python-novaclient Branch: refs/heads/master
-rw-r--r--novaclient/client.py37
-rw-r--r--novaclient/shell.py56
-rw-r--r--novaclient/tests/unit/test_client.py4
-rw-r--r--novaclient/tests/unit/test_shell.py4
-rw-r--r--novaclient/tests/unit/v2/test_shell.py11
5 files changed, 34 insertions, 78 deletions
diff --git a/novaclient/client.py b/novaclient/client.py
index 85d618d..d7656da 100644
--- a/novaclient/client.py
+++ b/novaclient/client.py
@@ -24,8 +24,10 @@ import copy
24import functools 24import functools
25import hashlib 25import hashlib
26import logging 26import logging
27import pkgutil
27import re 28import re
28import socket 29import socket
30import warnings
29 31
30from keystoneclient import adapter 32from keystoneclient import adapter
31from oslo_utils import importutils 33from oslo_utils import importutils
@@ -41,11 +43,15 @@ except ImportError:
41from six.moves.urllib import parse 43from six.moves.urllib import parse
42 44
43from novaclient import exceptions 45from novaclient import exceptions
44from novaclient.i18n import _ 46from novaclient.i18n import _, _LW
45from novaclient import service_catalog 47from novaclient import service_catalog
46from novaclient import utils 48from novaclient import utils
47 49
48 50
51# key is a deprecated version and value is an alternative version.
52DEPRECATED_VERSIONS = {"1.1": "2"}
53
54
49class TCPKeepAliveAdapter(adapters.HTTPAdapter): 55class TCPKeepAliveAdapter(adapters.HTTPAdapter):
50 """The custom adapter used to set TCP Keep-Alive on all connections.""" 56 """The custom adapter used to set TCP Keep-Alive on all connections."""
51 def init_poolmanager(self, *args, **kwargs): 57 def init_poolmanager(self, *args, **kwargs):
@@ -712,21 +718,30 @@ def _construct_http_client(username=None, password=None, project_id=None,
712 718
713 719
714def get_client_class(version): 720def get_client_class(version):
715 version_map = { 721 version = str(version)
716 '1.1': 'novaclient.v2.client.Client', 722 if version in DEPRECATED_VERSIONS:
717 '2': 'novaclient.v2.client.Client', 723 warnings.warn(_LW(
718 '3': 'novaclient.v2.client.Client', 724 "Version %(deprecated_version)s is deprecated, using "
719 } 725 "alternative version %(alternative)s instead.") %
726 {"deprecated_version": version,
727 "alternative": DEPRECATED_VERSIONS[version]})
728 version = DEPRECATED_VERSIONS[version]
720 try: 729 try:
721 client_path = version_map[str(version)] 730 return importutils.import_class(
722 except (KeyError, ValueError): 731 "novaclient.v%s.client.Client" % version)
732 except ImportError:
733 # NOTE(andreykurilin): available clients version should not be
734 # hardcoded, so let's discover them.
735 matcher = re.compile(r"v[0-9_]*$")
736 submodules = pkgutil.iter_modules(['novaclient'])
737 available_versions = [
738 name[1:].replace("_", ".") for loader, name, ispkg in submodules
739 if matcher.search(name)]
723 msg = _("Invalid client version '%(version)s'. must be one of: " 740 msg = _("Invalid client version '%(version)s'. must be one of: "
724 "%(keys)s") % {'version': version, 741 "%(keys)s") % {'version': version,
725 'keys': ', '.join(version_map.keys())} 742 'keys': ', '.join(available_versions)}
726 raise exceptions.UnsupportedVersion(msg) 743 raise exceptions.UnsupportedVersion(msg)
727 744
728 return importutils.import_class(client_path)
729
730 745
731def Client(version, *args, **kwargs): 746def Client(version, *args, **kwargs):
732 client_class = get_client_class(version) 747 client_class = get_client_class(version)
diff --git a/novaclient/shell.py b/novaclient/shell.py
index 4e7b5c9..5151635 100644
--- a/novaclient/shell.py
+++ b/novaclient/shell.py
@@ -58,13 +58,7 @@ from novaclient.v2 import shell as shell_v2
58 58
59DEFAULT_OS_COMPUTE_API_VERSION = "2" 59DEFAULT_OS_COMPUTE_API_VERSION = "2"
60DEFAULT_NOVA_ENDPOINT_TYPE = 'publicURL' 60DEFAULT_NOVA_ENDPOINT_TYPE = 'publicURL'
61# NOTE(cyeoh): Having the service type dependent on the API version 61DEFAULT_NOVA_SERVICE_TYPE = "compute"
62# is pretty ugly, but we have to do this because traditionally the
63# catalog entry for compute points directly to the V2 API rather than
64# the root, and then doing version discovery.
65DEFAULT_NOVA_SERVICE_TYPE_MAP = {'1.1': 'compute',
66 '2': 'compute',
67 '3': 'computev3'}
68 62
69logger = logging.getLogger(__name__) 63logger = logging.getLogger(__name__)
70 64
@@ -414,7 +408,7 @@ class OpenStackComputeShell(object):
414 metavar='<compute-api-ver>', 408 metavar='<compute-api-ver>',
415 default=cliutils.env('OS_COMPUTE_API_VERSION', 409 default=cliutils.env('OS_COMPUTE_API_VERSION',
416 default=DEFAULT_OS_COMPUTE_API_VERSION), 410 default=DEFAULT_OS_COMPUTE_API_VERSION),
417 help=_('Accepts 1.1 or 3, ' 411 help=_('Accepts number of API version, '
418 'defaults to env[OS_COMPUTE_API_VERSION].')) 412 'defaults to env[OS_COMPUTE_API_VERSION].'))
419 parser.add_argument( 413 parser.add_argument(
420 '--os_compute_api_version', 414 '--os_compute_api_version',
@@ -490,9 +484,9 @@ class OpenStackComputeShell(object):
490 def _discover_via_contrib_path(self, version): 484 def _discover_via_contrib_path(self, version):
491 module_path = os.path.dirname(os.path.abspath(__file__)) 485 module_path = os.path.dirname(os.path.abspath(__file__))
492 version_str = "v%s" % version.replace('.', '_') 486 version_str = "v%s" % version.replace('.', '_')
493 # NOTE(akurilin): v1.1, v2 and v3 have one implementation, so 487 # NOTE(andreykurilin): v1.1 uses implementation of v2, so we should
494 # we should discover contrib modules in one place. 488 # discover contrib modules in novaclient.v2 dir.
495 if version_str in ["v1_1", "v3"]: 489 if version_str == "v1_1":
496 version_str = "v2" 490 version_str = "v2"
497 ext_path = os.path.join(module_path, version_str, 'contrib') 491 ext_path = os.path.join(module_path, version_str, 'contrib')
498 ext_glob = os.path.join(ext_path, "*.py") 492 ext_glob = os.path.join(ext_path, "*.py")
@@ -656,15 +650,8 @@ class OpenStackComputeShell(object):
656 endpoint_type += 'URL' 650 endpoint_type += 'URL'
657 651
658 if not service_type: 652 if not service_type:
659 os_compute_api_version = (options.os_compute_api_version or 653 service_type = (cliutils.get_service_type(args.func) or
660 DEFAULT_OS_COMPUTE_API_VERSION) 654 DEFAULT_NOVA_SERVICE_TYPE)
661 try:
662 service_type = DEFAULT_NOVA_SERVICE_TYPE_MAP[
663 os_compute_api_version]
664 except KeyError:
665 service_type = DEFAULT_NOVA_SERVICE_TYPE_MAP[
666 DEFAULT_OS_COMPUTE_API_VERSION]
667 service_type = cliutils.get_service_type(args.func) or service_type
668 655
669 # If we have an auth token but no management_url, we must auth anyway. 656 # If we have an auth token but no management_url, we must auth anyway.
670 # Expired tokens are handled by client.py:_cs_request 657 # Expired tokens are handled by client.py:_cs_request
@@ -734,8 +721,7 @@ class OpenStackComputeShell(object):
734 project_domain_id=args.os_project_domain_id, 721 project_domain_id=args.os_project_domain_id,
735 project_domain_name=args.os_project_domain_name) 722 project_domain_name=args.os_project_domain_name)
736 723
737 if (options.os_compute_api_version and 724 if options.os_compute_api_version:
738 options.os_compute_api_version != '1.0'):
739 if not any([args.os_tenant_id, args.os_tenant_name, 725 if not any([args.os_tenant_id, args.os_tenant_name,
740 args.os_project_id, args.os_project_name]): 726 args.os_project_id, args.os_project_name]):
741 raise exc.CommandError(_("You must provide a project name or" 727 raise exc.CommandError(_("You must provide a project name or"
@@ -806,32 +792,6 @@ class OpenStackComputeShell(object):
806 except exc.AuthorizationFailure: 792 except exc.AuthorizationFailure:
807 raise exc.CommandError(_("Unable to authorize user")) 793 raise exc.CommandError(_("Unable to authorize user"))
808 794
809 if options.os_compute_api_version == "3" and service_type != 'image':
810 # NOTE(cyeoh): create an image based client because the
811 # images api is no longer proxied by the V3 API and we
812 # sometimes need to be able to look up images information
813 # via glance when connected to the nova api.
814 image_service_type = 'image'
815 # NOTE(hdd): the password is needed again because creating a new
816 # Client without specifying bypass_url will force authentication.
817 # We can't reuse self.cs's bypass_url, because that's the URL for
818 # the nova service; we need to get glance's URL for this Client
819 if not os_password:
820 os_password = helper.password
821 self.cs.image_cs = client.Client(
822 options.os_compute_api_version, os_username,
823 os_password, os_tenant_name, tenant_id=os_tenant_id,
824 auth_url=os_auth_url, insecure=insecure,
825 region_name=os_region_name, endpoint_type=endpoint_type,
826 extensions=self.extensions, service_type=image_service_type,
827 service_name=service_name, auth_system=os_auth_system,
828 auth_plugin=auth_plugin,
829 volume_service_name=volume_service_name,
830 timings=args.timings, bypass_url=bypass_url,
831 os_cache=os_cache, http_log_debug=options.debug,
832 session=keystone_session, auth=keystone_auth,
833 cacert=cacert, timeout=timeout)
834
835 args.func(self.cs, args) 795 args.func(self.cs, args)
836 796
837 if args.timings: 797 if args.timings:
diff --git a/novaclient/tests/unit/test_client.py b/novaclient/tests/unit/test_client.py
index 805278c..a828503 100644
--- a/novaclient/tests/unit/test_client.py
+++ b/novaclient/tests/unit/test_client.py
@@ -161,10 +161,6 @@ class ClientTest(utils.TestCase):
161 self._check_version_url('http://foo.com/nova/v2/%s', 161 self._check_version_url('http://foo.com/nova/v2/%s',
162 'http://foo.com/nova/') 162 'http://foo.com/nova/')
163 163
164 def test_get_client_class_v3(self):
165 output = novaclient.client.get_client_class('3')
166 self.assertEqual(output, novaclient.v2.client.Client)
167
168 def test_get_client_class_v2(self): 164 def test_get_client_class_v2(self):
169 output = novaclient.client.get_client_class('2') 165 output = novaclient.client.get_client_class('2')
170 self.assertEqual(output, novaclient.v2.client.Client) 166 self.assertEqual(output, novaclient.v2.client.Client)
diff --git a/novaclient/tests/unit/test_shell.py b/novaclient/tests/unit/test_shell.py
index f284eb8..a8826de 100644
--- a/novaclient/tests/unit/test_shell.py
+++ b/novaclient/tests/unit/test_shell.py
@@ -343,10 +343,6 @@ class ShellTest(utils.TestCase):
343 self._test_service_type('2', 'compute', mock_client) 343 self._test_service_type('2', 'compute', mock_client)
344 344
345 @mock.patch('novaclient.client.Client') 345 @mock.patch('novaclient.client.Client')
346 def test_v3_service_type(self, mock_client):
347 self._test_service_type('3', 'computev3', mock_client)
348
349 @mock.patch('novaclient.client.Client')
350 def test_v_unknown_service_type(self, mock_client): 346 def test_v_unknown_service_type(self, mock_client):
351 self._test_service_type('unknown', 'compute', mock_client) 347 self._test_service_type('unknown', 'compute', mock_client)
352 348
diff --git a/novaclient/tests/unit/v2/test_shell.py b/novaclient/tests/unit/v2/test_shell.py
index 139ea18..0abc345 100644
--- a/novaclient/tests/unit/v2/test_shell.py
+++ b/novaclient/tests/unit/v2/test_shell.py
@@ -2374,17 +2374,6 @@ class ShellTestV11(ShellTest):
2374 } 2374 }
2375 2375
2376 2376
2377class ShellTestV3(ShellTest):
2378 FAKE_ENV = {
2379 'NOVA_USERNAME': 'username',
2380 'NOVA_PASSWORD': 'password',
2381 'NOVA_PROJECT_ID': 'project_id',
2382 'OS_COMPUTE_API_VERSION': '3',
2383 'NOVA_URL': 'http://no.where',
2384 'OS_AUTH_URL': 'http://no.where/v2.0',
2385 }
2386
2387
2388class ShellWithSessionClientTest(ShellTest): 2377class ShellWithSessionClientTest(ShellTest):
2389 2378
2390 def setUp(self): 2379 def setUp(self):