Support API version discovery
This commit adds version discovery when user doesn't explicitly request a version or request the latest version. The latest version means the most recently version between server and client. Change-Id: I17be26342add9e9f4e3c384cc4aad613902e04a9 Implements: blueprint api-version-negotiation
This commit is contained in:
@@ -32,7 +32,7 @@ HEADER_NAME = "OpenStack-API-Version"
|
|||||||
SERVICE_TYPE = "container"
|
SERVICE_TYPE = "container"
|
||||||
MIN_API_VERSION = '1.1'
|
MIN_API_VERSION = '1.1'
|
||||||
MAX_API_VERSION = '1.25'
|
MAX_API_VERSION = '1.25'
|
||||||
DEFAULT_API_VERSION = MAX_API_VERSION
|
DEFAULT_API_VERSION = '1.latest'
|
||||||
|
|
||||||
_SUBSTITUTIONS = {}
|
_SUBSTITUTIONS = {}
|
||||||
|
|
||||||
@@ -231,13 +231,68 @@ def get_api_version(version_string):
|
|||||||
"""Returns checked APIVersion object"""
|
"""Returns checked APIVersion object"""
|
||||||
version_string = str(version_string)
|
version_string = str(version_string)
|
||||||
if strutils.is_int_like(version_string):
|
if strutils.is_int_like(version_string):
|
||||||
version_string = "%s.0" % version_string
|
version_string = "%s.latest" % version_string
|
||||||
|
|
||||||
api_version = APIVersion(version_string)
|
api_version = APIVersion(version_string)
|
||||||
check_major_version(api_version)
|
check_major_version(api_version)
|
||||||
return api_version
|
return api_version
|
||||||
|
|
||||||
|
|
||||||
|
def _get_server_version_range(client):
|
||||||
|
version = client.versions.get_current()
|
||||||
|
|
||||||
|
if not hasattr(version, 'max_version') or not version.max_version:
|
||||||
|
return APIVersion(), APIVersion()
|
||||||
|
|
||||||
|
return APIVersion(version.min_version), APIVersion(version.max_version)
|
||||||
|
|
||||||
|
|
||||||
|
def discover_version(client, requested_version):
|
||||||
|
server_start_version, server_end_version = _get_server_version_range(
|
||||||
|
client)
|
||||||
|
|
||||||
|
if (not requested_version.is_latest() and
|
||||||
|
requested_version != APIVersion('1.1')):
|
||||||
|
if server_start_version.is_null() and server_end_version.is_null():
|
||||||
|
raise exceptions.UnsupportedVersion(
|
||||||
|
_("Server doesn't support microversions"))
|
||||||
|
if not requested_version.matches(server_start_version,
|
||||||
|
server_end_version):
|
||||||
|
raise exceptions.UnsupportedVersion(
|
||||||
|
_("The specified version isn't supported by server. The valid "
|
||||||
|
"version range is '%(min)s' to '%(max)s'") % {
|
||||||
|
"min": server_start_version.get_string(),
|
||||||
|
"max": server_end_version.get_string()})
|
||||||
|
return requested_version
|
||||||
|
|
||||||
|
min_version = APIVersion(MIN_API_VERSION)
|
||||||
|
max_version = APIVersion(MAX_API_VERSION)
|
||||||
|
if server_start_version.is_null() and server_end_version.is_null():
|
||||||
|
return APIVersion("1.1")
|
||||||
|
elif min_version > server_end_version:
|
||||||
|
raise exceptions.UnsupportedVersion(
|
||||||
|
_("Server version is too old. The client valid version range is "
|
||||||
|
"'%(client_min)s' to '%(client_max)s'. The server valid version "
|
||||||
|
"range is '%(server_min)s' to '%(server_max)s'.") % {
|
||||||
|
'client_min': min_version.get_string(),
|
||||||
|
'client_max': max_version.get_string(),
|
||||||
|
'server_min': server_start_version.get_string(),
|
||||||
|
'server_max': server_end_version.get_string()})
|
||||||
|
elif max_version < server_start_version:
|
||||||
|
raise exceptions.UnsupportedVersion(
|
||||||
|
_("Server version is too new. The client valid version range is "
|
||||||
|
"'%(client_min)s' to '%(client_max)s'. The server valid version "
|
||||||
|
"range is '%(server_min)s' to '%(server_max)s'.") % {
|
||||||
|
'client_min': min_version.get_string(),
|
||||||
|
'client_max': max_version.get_string(),
|
||||||
|
'server_min': server_start_version.get_string(),
|
||||||
|
'server_max': server_end_version.get_string()})
|
||||||
|
elif max_version <= server_end_version:
|
||||||
|
return max_version
|
||||||
|
elif server_end_version < max_version:
|
||||||
|
return server_end_version
|
||||||
|
|
||||||
|
|
||||||
def update_headers(headers, api_version):
|
def update_headers(headers, api_version):
|
||||||
"""Set microversion headers if api_version is not null"""
|
"""Set microversion headers if api_version is not null"""
|
||||||
|
|
||||||
|
@@ -17,8 +17,6 @@ import warnings
|
|||||||
from oslo_utils import importutils
|
from oslo_utils import importutils
|
||||||
|
|
||||||
from zunclient import api_versions
|
from zunclient import api_versions
|
||||||
from zunclient import exceptions
|
|
||||||
from zunclient.i18n import _
|
|
||||||
|
|
||||||
osprofiler_profiler = importutils.try_import("osprofiler.profiler")
|
osprofiler_profiler = importutils.try_import("osprofiler.profiler")
|
||||||
|
|
||||||
@@ -28,9 +26,6 @@ def _get_client_class_and_version(version):
|
|||||||
version = api_versions.get_api_version(version)
|
version = api_versions.get_api_version(version)
|
||||||
else:
|
else:
|
||||||
api_versions.check_major_version(version)
|
api_versions.check_major_version(version)
|
||||||
if version.is_latest():
|
|
||||||
raise exceptions.UnsupportedVersion(
|
|
||||||
_('The version should be explicit, not latest.'))
|
|
||||||
return version, importutils.import_class(
|
return version, importutils.import_class(
|
||||||
'zunclient.v%s.client.Client' % version.ver_major)
|
'zunclient.v%s.client.Client' % version.ver_major)
|
||||||
|
|
||||||
|
@@ -22,26 +22,36 @@ LOG = logging.getLogger(__name__)
|
|||||||
DEFAULT_CONTAINER_API_VERSION = api_versions.DEFAULT_API_VERSION
|
DEFAULT_CONTAINER_API_VERSION = api_versions.DEFAULT_API_VERSION
|
||||||
API_VERSION_OPTION = "os_container_api_version"
|
API_VERSION_OPTION = "os_container_api_version"
|
||||||
API_NAME = "container"
|
API_NAME = "container"
|
||||||
LAST_KNOWN_API_VERSION = int(DEFAULT_CONTAINER_API_VERSION.split('.')[1])
|
CLIENT_CLASS = 'zunclient.v1.client.Client'
|
||||||
|
LAST_KNOWN_API_VERSION = int(api_versions.MAX_API_VERSION.split('.')[1])
|
||||||
API_VERSIONS = {
|
API_VERSIONS = {
|
||||||
'1.%d' % i: 'zunclient.v1.client.Client'
|
'1.%d' % i: CLIENT_CLASS
|
||||||
for i in range(1, LAST_KNOWN_API_VERSION + 1)
|
for i in range(1, LAST_KNOWN_API_VERSION + 1)
|
||||||
}
|
}
|
||||||
API_VERSIONS['1'] = API_VERSIONS[DEFAULT_CONTAINER_API_VERSION]
|
API_VERSIONS['1'] = CLIENT_CLASS
|
||||||
|
|
||||||
|
|
||||||
def make_client(instance):
|
def make_client(instance):
|
||||||
"""Returns a zun service client"""
|
"""Returns a zun service client"""
|
||||||
|
requested_api_version = instance._api_version[API_NAME]
|
||||||
|
|
||||||
zun_client = utils.get_client_class(
|
zun_client = utils.get_client_class(
|
||||||
API_NAME,
|
API_NAME,
|
||||||
instance._api_version[API_NAME],
|
requested_api_version,
|
||||||
API_VERSIONS)
|
API_VERSIONS)
|
||||||
LOG.debug("Instantiating zun client: {0}".format(
|
LOG.debug("Instantiating zun client: {0}".format(
|
||||||
zun_client))
|
zun_client))
|
||||||
|
|
||||||
# TODO(hongbin): Instead of hard-coding api-version to 'latest', it is
|
api_version = api_versions.get_api_version(requested_api_version)
|
||||||
# better to read micro-version from CLI (bug #1701939).
|
if api_version.is_latest():
|
||||||
api_version = api_versions.get_api_version(instance._api_version[API_NAME])
|
client = zun_client(
|
||||||
|
region_name=instance._region_name,
|
||||||
|
session=instance.session,
|
||||||
|
service_type='container',
|
||||||
|
api_version=api_versions.APIVersion("1.1"),
|
||||||
|
)
|
||||||
|
api_version = api_versions.discover_version(client, api_version)
|
||||||
|
|
||||||
client = zun_client(
|
client = zun_client(
|
||||||
region_name=instance._region_name,
|
region_name=instance._region_name,
|
||||||
session=instance.session,
|
session=instance.session,
|
||||||
@@ -56,26 +66,38 @@ def build_option_parser(parser):
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--os-container-api-version',
|
'--os-container-api-version',
|
||||||
metavar='<container-api-version>',
|
metavar='<container-api-version>',
|
||||||
default=utils.env(
|
default=_get_environment_version(DEFAULT_CONTAINER_API_VERSION),
|
||||||
'OS_CONTAINER_API_VERSION',
|
|
||||||
default=DEFAULT_CONTAINER_API_VERSION),
|
|
||||||
action=ReplaceLatestVersion,
|
action=ReplaceLatestVersion,
|
||||||
choices=sorted(
|
choices=sorted(
|
||||||
API_VERSIONS,
|
API_VERSIONS,
|
||||||
key=lambda k: [int(x) for x in k.split('.')]) + ['latest'],
|
key=lambda k: [int(x) for x in k.split('.')]) + ['1.latest'],
|
||||||
help=("Container API version, default={0}"
|
help=("Container API version, default={0}"
|
||||||
"(Env:OS_CONTAINER_API_VERSION)").format(
|
"(Env:OS_CONTAINER_API_VERSION)").format(
|
||||||
DEFAULT_CONTAINER_API_VERSION))
|
DEFAULT_CONTAINER_API_VERSION))
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
|
def _get_environment_version(default):
|
||||||
|
env_value = utils.env('OS_CONTAINER_API_VERSION') or default
|
||||||
|
latest = env_value == '1.latest'
|
||||||
|
if latest:
|
||||||
|
# NOTE(hongbin): '1.latest' means enabling negotiation of the
|
||||||
|
# latest version between server and client but due to how OSC works
|
||||||
|
# we cannot just add "1.latest" to the list of supported versions.
|
||||||
|
# Use '1' in this case.
|
||||||
|
env_value = '1'
|
||||||
|
return env_value
|
||||||
|
|
||||||
|
|
||||||
class ReplaceLatestVersion(argparse.Action):
|
class ReplaceLatestVersion(argparse.Action):
|
||||||
"""Replaces `latest` keyword by last known version."""
|
"""Replaces `latest` keyword by last known version."""
|
||||||
|
|
||||||
def __call__(self, parser, namespace, values, option_string=None):
|
def __call__(self, parser, namespace, values, option_string=None):
|
||||||
latest = values == 'latest'
|
latest = values == '1.latest'
|
||||||
if latest:
|
if latest:
|
||||||
values = '1.%d' % LAST_KNOWN_API_VERSION
|
# NOTE(hongbin): '1.latest' means enabling negotiation of the
|
||||||
LOG.debug("Replacing 'latest' API version with the "
|
# latest version between server and client but due to how OSC works
|
||||||
"latest known version '%s'", values)
|
# we cannot just add "1.latest" to the list of supported versions.
|
||||||
|
# Use '1' in this case.
|
||||||
|
values = '1'
|
||||||
setattr(namespace, self.dest, values)
|
setattr(namespace, self.dest, values)
|
||||||
|
@@ -335,7 +335,8 @@ class OpenStackZunShell(object):
|
|||||||
'ZUN_API_VERSION',
|
'ZUN_API_VERSION',
|
||||||
default=DEFAULT_API_VERSION),
|
default=DEFAULT_API_VERSION),
|
||||||
help='Accepts X, X.Y (where X is major, Y is minor'
|
help='Accepts X, X.Y (where X is major, Y is minor'
|
||||||
' part), defaults to env[ZUN_API_VERSION].')
|
' part) or "X.latest", defaults to'
|
||||||
|
' env[ZUN_API_VERSION].')
|
||||||
parser.add_argument('--zun_api_version',
|
parser.add_argument('--zun_api_version',
|
||||||
help=argparse.SUPPRESS)
|
help=argparse.SUPPRESS)
|
||||||
|
|
||||||
@@ -517,8 +518,9 @@ class OpenStackZunShell(object):
|
|||||||
spot = argv.index('--endpoint_type')
|
spot = argv.index('--endpoint_type')
|
||||||
argv[spot] = '--endpoint-type'
|
argv[spot] = '--endpoint-type'
|
||||||
|
|
||||||
|
do_help = "help" in args
|
||||||
subcommand_parser = self.get_subcommand_parser(
|
subcommand_parser = self.get_subcommand_parser(
|
||||||
api_version, do_help=("help" in args))
|
api_version, do_help=do_help)
|
||||||
|
|
||||||
self.parser = subcommand_parser
|
self.parser = subcommand_parser
|
||||||
|
|
||||||
@@ -625,6 +627,42 @@ class OpenStackZunShell(object):
|
|||||||
|
|
||||||
client = base_client
|
client = base_client
|
||||||
|
|
||||||
|
if not do_help:
|
||||||
|
if api_version.is_latest():
|
||||||
|
# This client is just used to discover api version.
|
||||||
|
# Version API needn't microversion, so we just pass
|
||||||
|
# version 1.1 at here.
|
||||||
|
self.cs = client.Client(
|
||||||
|
version=api_versions.APIVersion("1.1"),
|
||||||
|
username=os_username,
|
||||||
|
password=os_password,
|
||||||
|
project_id=os_project_id,
|
||||||
|
project_name=os_project_name,
|
||||||
|
user_domain_id=os_user_domain_id,
|
||||||
|
user_domain_name=os_user_domain_name,
|
||||||
|
project_domain_id=os_project_domain_id,
|
||||||
|
project_domain_name=os_project_domain_name,
|
||||||
|
auth_url=os_auth_url,
|
||||||
|
service_type=service_type,
|
||||||
|
region_name=args.os_region_name,
|
||||||
|
endpoint_override=bypass_url,
|
||||||
|
interface=endpoint_type,
|
||||||
|
insecure=insecure,
|
||||||
|
cacert=os_cacert)
|
||||||
|
api_version = api_versions.discover_version(self.cs,
|
||||||
|
api_version)
|
||||||
|
|
||||||
|
min_version = api_versions.APIVersion(api_versions.MIN_API_VERSION)
|
||||||
|
max_version = api_versions.APIVersion(api_versions.MAX_API_VERSION)
|
||||||
|
if not api_version.matches(min_version, max_version):
|
||||||
|
raise exc.CommandError(
|
||||||
|
_("The specified version isn't supported by "
|
||||||
|
"client. The valid version range is '%(min)s' "
|
||||||
|
"to '%(max)s'") % {
|
||||||
|
"min": min_version.get_string(),
|
||||||
|
"max": max_version.get_string()}
|
||||||
|
)
|
||||||
|
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
if profiler:
|
if profiler:
|
||||||
kwargs["profile"] = args.profile
|
kwargs["profile"] = args.profile
|
||||||
|
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
|
from zunclient import api_versions
|
||||||
from zunclient.osc import plugin
|
from zunclient.osc import plugin
|
||||||
from zunclient.tests.unit import base
|
from zunclient.tests.unit import base
|
||||||
|
|
||||||
@@ -26,10 +27,10 @@ class TestContainerPlugin(base.TestCase):
|
|||||||
instance._api_version = {"container": '1'}
|
instance._api_version = {"container": '1'}
|
||||||
instance._region_name = 'zun_region'
|
instance._region_name = 'zun_region'
|
||||||
instance.session = 'zun_session'
|
instance.session = 'zun_session'
|
||||||
mock_get_api_version.return_value = '1.2'
|
mock_get_api_version.return_value = api_versions.APIVersion('1.2')
|
||||||
|
|
||||||
plugin.make_client(instance)
|
plugin.make_client(instance)
|
||||||
p_client.assert_called_with(region_name='zun_region',
|
p_client.assert_called_with(region_name='zun_region',
|
||||||
session='zun_session',
|
session='zun_session',
|
||||||
service_type='container',
|
service_type='container',
|
||||||
api_version='1.2')
|
api_version=api_versions.APIVersion('1.2'))
|
||||||
|
@@ -18,6 +18,7 @@ import mock
|
|||||||
from zunclient import api_versions
|
from zunclient import api_versions
|
||||||
from zunclient import exceptions
|
from zunclient import exceptions
|
||||||
from zunclient.tests.unit import utils
|
from zunclient.tests.unit import utils
|
||||||
|
from zunclient.v1 import versions
|
||||||
|
|
||||||
|
|
||||||
class APIVersionTestCase(utils.TestCase):
|
class APIVersionTestCase(utils.TestCase):
|
||||||
@@ -157,7 +158,7 @@ class GetAPIVersionTestCase(utils.TestCase):
|
|||||||
version = 7
|
version = 7
|
||||||
self.assertEqual(mock_apiversion.return_value,
|
self.assertEqual(mock_apiversion.return_value,
|
||||||
api_versions.get_api_version(version))
|
api_versions.get_api_version(version))
|
||||||
mock_apiversion.assert_called_once_with("%s.0" % str(version))
|
mock_apiversion.assert_called_once_with("%s.latest" % str(version))
|
||||||
|
|
||||||
@mock.patch("zunclient.api_versions.APIVersion")
|
@mock.patch("zunclient.api_versions.APIVersion")
|
||||||
def test_major_and_minor_parts_is_presented(self, mock_apiversion):
|
def test_major_and_minor_parts_is_presented(self, mock_apiversion):
|
||||||
@@ -244,3 +245,88 @@ class WrapsTestCase(utils.TestCase):
|
|||||||
some_func(obj, *some_args, **some_kwargs)
|
some_func(obj, *some_args, **some_kwargs)
|
||||||
|
|
||||||
checker.assert_called_once_with(*((obj,) + some_args), **some_kwargs)
|
checker.assert_called_once_with(*((obj,) + some_args), **some_kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class DiscoverVersionTestCase(utils.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
super(DiscoverVersionTestCase, self).setUp()
|
||||||
|
self.orig_max = api_versions.MAX_API_VERSION
|
||||||
|
self.orig_min = api_versions.MIN_API_VERSION
|
||||||
|
self.addCleanup(self._clear_fake_version)
|
||||||
|
|
||||||
|
def _clear_fake_version(self):
|
||||||
|
api_versions.MAX_API_VERSION = self.orig_max
|
||||||
|
api_versions.MIN_API_VERSION = self.orig_min
|
||||||
|
|
||||||
|
def test_server_is_too_new(self):
|
||||||
|
fake_client = mock.MagicMock()
|
||||||
|
fake_client.versions.get_current.return_value = mock.MagicMock(
|
||||||
|
max_version="1.7", min_version="1.4")
|
||||||
|
api_versions.MAX_API_VERSION = "1.3"
|
||||||
|
api_versions.MIN_API_VERSION = "1.1"
|
||||||
|
self.assertRaises(exceptions.UnsupportedVersion,
|
||||||
|
api_versions.discover_version, fake_client,
|
||||||
|
api_versions.APIVersion('1.latest'))
|
||||||
|
|
||||||
|
def test_server_is_too_old(self):
|
||||||
|
fake_client = mock.MagicMock()
|
||||||
|
fake_client.versions.get_current.return_value = mock.MagicMock(
|
||||||
|
max_version="1.7", min_version="1.4")
|
||||||
|
api_versions.MAX_API_VERSION = "1.10"
|
||||||
|
api_versions.MIN_API_VERSION = "1.9"
|
||||||
|
|
||||||
|
self.assertRaises(exceptions.UnsupportedVersion,
|
||||||
|
api_versions.discover_version, fake_client,
|
||||||
|
api_versions.APIVersion('1.latest'))
|
||||||
|
|
||||||
|
def test_server_end_version_is_the_latest_one(self):
|
||||||
|
fake_client = mock.MagicMock()
|
||||||
|
fake_client.versions.get_current.return_value = mock.MagicMock(
|
||||||
|
max_version="1.7", min_version="1.4")
|
||||||
|
api_versions.MAX_API_VERSION = "1.11"
|
||||||
|
api_versions.MIN_API_VERSION = "1.1"
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
"1.7",
|
||||||
|
api_versions.discover_version(
|
||||||
|
fake_client,
|
||||||
|
api_versions.APIVersion('1.latest')).get_string())
|
||||||
|
|
||||||
|
def test_client_end_version_is_the_latest_one(self):
|
||||||
|
fake_client = mock.MagicMock()
|
||||||
|
fake_client.versions.get_current.return_value = mock.MagicMock(
|
||||||
|
max_version="1.16", min_version="1.4")
|
||||||
|
api_versions.MAX_API_VERSION = "1.11"
|
||||||
|
api_versions.MIN_API_VERSION = "1.1"
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
"1.11",
|
||||||
|
api_versions.discover_version(
|
||||||
|
fake_client,
|
||||||
|
api_versions.APIVersion('1.latest')).get_string())
|
||||||
|
|
||||||
|
def test_server_without_microversion(self):
|
||||||
|
fake_client = mock.MagicMock()
|
||||||
|
fake_client.versions.get_current.return_value = mock.MagicMock(
|
||||||
|
max_version='', min_version='')
|
||||||
|
api_versions.MAX_API_VERSION = "1.11"
|
||||||
|
api_versions.MIN_API_VERSION = "1.1"
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
"1.1",
|
||||||
|
api_versions.discover_version(
|
||||||
|
fake_client,
|
||||||
|
api_versions.APIVersion('1.latest')).get_string())
|
||||||
|
|
||||||
|
def test_server_without_microversion_and_no_version_field(self):
|
||||||
|
fake_client = mock.MagicMock()
|
||||||
|
fake_client.versions.get_current.return_value = versions.Version(
|
||||||
|
None, {})
|
||||||
|
api_versions.MAX_API_VERSION = "1.11"
|
||||||
|
api_versions.MIN_API_VERSION = "1.1"
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
"1.1",
|
||||||
|
api_versions.discover_version(
|
||||||
|
fake_client,
|
||||||
|
api_versions.APIVersion('1.latest')).get_string())
|
||||||
|
@@ -82,6 +82,9 @@ class ShellTest(utils.TestCase):
|
|||||||
self.nc_util = mock.patch(
|
self.nc_util = mock.patch(
|
||||||
'zunclient.common.cliutils.isunauthenticated').start()
|
'zunclient.common.cliutils.isunauthenticated').start()
|
||||||
self.nc_util.return_value = False
|
self.nc_util.return_value = False
|
||||||
|
self.discover_version = mock.patch(
|
||||||
|
'zunclient.api_versions.discover_version').start()
|
||||||
|
self.discover_version.return_value = api_versions.APIVersion('1.1')
|
||||||
|
|
||||||
def test_help_unknown_command(self):
|
def test_help_unknown_command(self):
|
||||||
self.assertRaises(exceptions.CommandError, self.shell, 'help foofoo')
|
self.assertRaises(exceptions.CommandError, self.shell, 'help foofoo')
|
||||||
@@ -250,22 +253,29 @@ class ShellTest(utils.TestCase):
|
|||||||
|
|
||||||
def test_main_option_region(self):
|
def test_main_option_region(self):
|
||||||
self.make_env()
|
self.make_env()
|
||||||
self._test_main_region('--os-region-name=myregion service-list',
|
self._test_main_region(
|
||||||
'myregion')
|
'--zun-api-version 1.25 '
|
||||||
|
'--os-region-name=myregion service-list', 'myregion')
|
||||||
|
|
||||||
def test_main_env_region(self):
|
def test_main_env_region(self):
|
||||||
fake_env = dict(utils.FAKE_ENV, OS_REGION_NAME='myregion')
|
fake_env = dict(utils.FAKE_ENV, OS_REGION_NAME='myregion')
|
||||||
self.make_env(fake_env=fake_env)
|
self.make_env(fake_env=fake_env)
|
||||||
self._test_main_region('service-list', 'myregion')
|
self._test_main_region(
|
||||||
|
'--zun-api-version 1.25 '
|
||||||
|
'service-list', 'myregion')
|
||||||
|
|
||||||
def test_main_no_region(self):
|
def test_main_no_region(self):
|
||||||
self.make_env()
|
self.make_env()
|
||||||
self._test_main_region('service-list', None)
|
self._test_main_region(
|
||||||
|
'--zun-api-version 1.25 '
|
||||||
|
'service-list', None)
|
||||||
|
|
||||||
@mock.patch('zunclient.client.Client')
|
@mock.patch('zunclient.client.Client')
|
||||||
def test_main_endpoint_public(self, mock_client):
|
def test_main_endpoint_public(self, mock_client):
|
||||||
self.make_env()
|
self.make_env()
|
||||||
self.shell('--endpoint-type publicURL service-list')
|
self.shell(
|
||||||
|
'--zun-api-version 1.25 '
|
||||||
|
'--endpoint-type publicURL service-list')
|
||||||
mock_client.assert_called_once_with(
|
mock_client.assert_called_once_with(
|
||||||
username='username', password='password',
|
username='username', password='password',
|
||||||
interface='publicURL', project_id=None,
|
interface='publicURL', project_id=None,
|
||||||
@@ -279,7 +289,9 @@ class ShellTest(utils.TestCase):
|
|||||||
@mock.patch('zunclient.client.Client')
|
@mock.patch('zunclient.client.Client')
|
||||||
def test_main_endpoint_internal(self, mock_client):
|
def test_main_endpoint_internal(self, mock_client):
|
||||||
self.make_env()
|
self.make_env()
|
||||||
self.shell('--endpoint-type internalURL service-list')
|
self.shell(
|
||||||
|
'--zun-api-version 1.25 '
|
||||||
|
'--endpoint-type internalURL service-list')
|
||||||
mock_client.assert_called_once_with(
|
mock_client.assert_called_once_with(
|
||||||
username='username', password='password',
|
username='username', password='password',
|
||||||
interface='internalURL', project_id=None,
|
interface='internalURL', project_id=None,
|
||||||
@@ -310,7 +322,9 @@ class ShellTestKeystoneV3(ShellTest):
|
|||||||
@mock.patch('zunclient.client.Client')
|
@mock.patch('zunclient.client.Client')
|
||||||
def test_main_endpoint_public(self, mock_client):
|
def test_main_endpoint_public(self, mock_client):
|
||||||
self.make_env(fake_env=FAKE_ENV4)
|
self.make_env(fake_env=FAKE_ENV4)
|
||||||
self.shell('--endpoint-type publicURL service-list')
|
self.shell(
|
||||||
|
'--zun-api-version 1.25 '
|
||||||
|
'--endpoint-type publicURL service-list')
|
||||||
mock_client.assert_called_once_with(
|
mock_client.assert_called_once_with(
|
||||||
username='username', password='password',
|
username='username', password='password',
|
||||||
interface='publicURL', project_id='project_id',
|
interface='publicURL', project_id='project_id',
|
||||||
|
@@ -17,6 +17,7 @@ import re
|
|||||||
import mock
|
import mock
|
||||||
from testtools import matchers
|
from testtools import matchers
|
||||||
|
|
||||||
|
from zunclient import api_versions
|
||||||
from zunclient.tests.unit import utils
|
from zunclient.tests.unit import utils
|
||||||
|
|
||||||
FAKE_ENV = {'OS_USERNAME': 'username',
|
FAKE_ENV = {'OS_USERNAME': 'username',
|
||||||
@@ -67,10 +68,14 @@ class TestCommandLineArgument(utils.TestCase):
|
|||||||
loader.start()
|
loader.start()
|
||||||
session = mock.patch('keystoneauth1.session.Session')
|
session = mock.patch('keystoneauth1.session.Session')
|
||||||
session.start()
|
session.start()
|
||||||
|
discover = mock.patch('zunclient.api_versions.discover_version',
|
||||||
|
return_value=api_versions.APIVersion('1.1'))
|
||||||
|
discover.start()
|
||||||
|
|
||||||
self.addCleanup(session_client.stop)
|
self.addCleanup(session_client.stop)
|
||||||
self.addCleanup(loader.stop)
|
self.addCleanup(loader.stop)
|
||||||
self.addCleanup(session.stop)
|
self.addCleanup(session.stop)
|
||||||
|
self.addCleanup(discover.stop)
|
||||||
|
|
||||||
def _test_arg_success(self, command):
|
def _test_arg_success(self, command):
|
||||||
stdout, stderr = self.shell(command)
|
stdout, stderr = self.shell(command)
|
||||||
|
@@ -25,3 +25,9 @@ class VersionManager(base.Manager):
|
|||||||
url = "%s" % self.api.get_endpoint()
|
url = "%s" % self.api.get_endpoint()
|
||||||
url = "%s/" % url.rsplit("/", 1)[0]
|
url = "%s/" % url.rsplit("/", 1)[0]
|
||||||
return self._list(url, "versions")
|
return self._list(url, "versions")
|
||||||
|
|
||||||
|
def get_current(self):
|
||||||
|
for version in self.list():
|
||||||
|
if version.status == "CURRENT":
|
||||||
|
return version
|
||||||
|
return None
|
||||||
|
Reference in New Issue
Block a user