Skip to content

Commit 3abfea0

Browse files
author
Dean Troyer
committed
Fix compute API version snafu
novaclient 2.27.0 introduced the API microversion discovery and client.Client now wants an api_version argument to properly work out the correct API version in use. OSC needs to provide this when required. Letting the compute client plugin do the version validity checking makes more sense than encoding it into shell.py, so I've added a new OSC plugin interface function check_api_version() that is called from shell.py if it exists. If it either does not exist or it returns False the previous version checking using API_VERSIONS is still performed. compute.client.check_api_version() conditionally imports the new novaclient.api_versions module and uses it if successful. Otherwise check_api_version() returns False and the previous code path is resumed. One side-effect of this is that it is now valid to use --os-compute-api-version with any valid microversion supported by the installed python-novaclient. Closes-Bug: #1492467 Change-Id: I4535b38a5639a03a9597bf83f6394f9bb45c2b9e
1 parent 9210cac commit 3abfea0

2 files changed

Lines changed: 66 additions & 5 deletions

File tree

openstackclient/compute/client.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import logging
1717

18+
from openstackclient.common import exceptions
1819
from openstackclient.common import utils
1920

2021
LOG = logging.getLogger(__name__)
@@ -26,6 +27,9 @@
2627
"2": "novaclient.client",
2728
}
2829

30+
# Save the microversion if in use
31+
_compute_api_version = None
32+
2933

3034
def make_client(instance):
3135
"""Returns a compute service client."""
@@ -51,6 +55,9 @@ def make_client(instance):
5155
# Remember interface only if it is set
5256
kwargs = utils.build_kwargs_dict('endpoint_type', instance._interface)
5357

58+
if _compute_api_version is not None:
59+
kwargs.update({'api_version': _compute_api_version})
60+
5461
client = compute_client(
5562
session=instance.session,
5663
extensions=extensions,
@@ -73,3 +80,45 @@ def build_option_parser(parser):
7380
DEFAULT_API_VERSION +
7481
' (Env: OS_COMPUTE_API_VERSION)')
7582
return parser
83+
84+
85+
def check_api_version(check_version):
86+
"""Validate version supplied by user
87+
88+
Returns:
89+
* True if version is OK
90+
* False if the version has not been checked and the previous plugin
91+
check should be performed
92+
* throws an exception if the version is no good
93+
94+
TODO(dtroyer): make the exception thrown a version-related one
95+
"""
96+
97+
# Defer client imports until we actually need them
98+
try:
99+
from novaclient import api_versions
100+
except ImportError:
101+
# Retain previous behaviour
102+
return False
103+
104+
import novaclient
105+
106+
global _compute_api_version
107+
108+
# Copy some logic from novaclient 2.27.0 for basic version detection
109+
# NOTE(dtroyer): This is only enough to resume operations using API
110+
# version 2.0 or any valid version supplied by the user.
111+
_compute_api_version = api_versions.get_api_version(check_version)
112+
113+
if _compute_api_version > api_versions.APIVersion("2.0"):
114+
if not _compute_api_version.matches(
115+
novaclient.API_MIN_VERSION,
116+
novaclient.API_MAX_VERSION,
117+
):
118+
raise exceptions.CommandError(
119+
"versions supported by client: %s - %s" % (
120+
novaclient.API_MIN_VERSION.get_string(),
121+
novaclient.API_MAX_VERSION.get_string(),
122+
),
123+
)
124+
return True

openstackclient/shell.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -304,11 +304,23 @@ def initialize_app(self, argv):
304304
if version_opt:
305305
api = mod.API_NAME
306306
self.api_version[api] = version_opt
307-
if version_opt not in mod.API_VERSIONS:
308-
self.log.warning(
309-
"The %s version <%s> is not in supported versions <%s>"
310-
% (api, version_opt,
311-
', '.join(mod.API_VERSIONS.keys())))
307+
308+
# Add a plugin interface to let the module validate the version
309+
# requested by the user
310+
skip_old_check = False
311+
mod_check_api_version = getattr(mod, 'check_api_version', None)
312+
if mod_check_api_version:
313+
# this throws an exception if invalid
314+
skip_old_check = mod_check_api_version(version_opt)
315+
316+
mod_versions = getattr(mod, 'API_VERSIONS', None)
317+
if not skip_old_check and mod_versions:
318+
if version_opt not in mod_versions:
319+
self.log.warning(
320+
"%s version %s is not in supported versions %s"
321+
% (api, version_opt,
322+
', '.join(mod.API_VERSIONS.keys())))
323+
312324
# Command groups deal only with major versions
313325
version = '.v' + version_opt.replace('.', '_').split('_')[0]
314326
cmd_group = 'openstack.' + api.replace('-', '_') + version

0 commit comments

Comments
 (0)