Skip to content

Commit 95113c5

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Add version foot protector"
2 parents 7f257ab + 7d6ce96 commit 95113c5

File tree

3 files changed

+73
-23
lines changed

3 files changed

+73
-23
lines changed

novaclient/api_versions.py

Lines changed: 46 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
import functools
1515
import logging
1616
import os
17-
import pkgutil
1817
import re
1918
import traceback
2019
import warnings
@@ -195,35 +194,59 @@ def __repr__(self):
195194

196195

197196
def get_available_major_versions():
198-
# NOTE(andreykurilin): available clients version should not be
199-
# hardcoded, so let's discover them.
200-
matcher = re.compile(r"v[0-9]*$")
201-
submodules = pkgutil.iter_modules([os.path.dirname(__file__)])
202-
available_versions = [name[1:] for loader, name, ispkg in submodules
203-
if matcher.search(name)]
204-
205-
return available_versions
197+
return ['2']
206198

207199

208200
def check_major_version(api_version):
209201
"""Checks major part of ``APIVersion`` obj is supported.
210202
211203
:raises novaclient.exceptions.UnsupportedVersion: if major part is not
212-
supported
204+
supported
213205
"""
214-
available_versions = get_available_major_versions()
215-
if (not api_version.is_null() and
216-
str(api_version.ver_major) not in available_versions):
217-
if len(available_versions) == 1:
218-
msg = _("Invalid client version '%(version)s'. "
219-
"Major part should be '%(major)s'") % {
220-
"version": api_version.get_string(),
221-
"major": available_versions[0]}
222-
else:
223-
msg = _("Invalid client version '%(version)s'. "
224-
"Major part must be one of: '%(major)s'") % {
225-
"version": api_version.get_string(),
226-
"major": ", ".join(available_versions)}
206+
if api_version.is_null():
207+
return
208+
209+
if api_version.ver_major == 2:
210+
return
211+
212+
msg = _(
213+
"Invalid client version '%(version)s'. Major part should be '2'"
214+
) % {"version": api_version.get_string()}
215+
raise exceptions.UnsupportedVersion(msg)
216+
217+
218+
def check_version(api_version):
219+
"""Checks if version of ``APIVersion`` is supported.
220+
221+
Provided as an alternative to :func:`check_major_version` to avoid changing
222+
the behavior of that function.
223+
224+
:raises novaclient.exceptions.UnsupportedVersion: if major part is not
225+
supported
226+
"""
227+
if api_version.is_null():
228+
return
229+
230+
# we can't use API_MIN_VERSION since we do support 2.0 (which is 2.1 but
231+
# less strict)
232+
if api_version < APIVersion('2.0'):
233+
msg = _(
234+
"Invalid client version '%(version)s'. "
235+
"Min version supported is '%(min_version)s'"
236+
) % {
237+
"version": api_version.get_string(),
238+
"min_version": novaclient.API_MIN_VERSION,
239+
}
240+
raise exceptions.UnsupportedVersion(msg)
241+
242+
if api_version > novaclient.API_MAX_VERSION:
243+
msg = _(
244+
"Invalid client version '%(version)s'. "
245+
"Max version supported is '%(max_version)s'"
246+
) % {
247+
"version": api_version.get_string(),
248+
"max_version": novaclient.API_MAX_VERSION,
249+
}
227250
raise exceptions.UnsupportedVersion(msg)
228251

229252

novaclient/client.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ def __init__(self, *args, **kwargs):
5151
self.timings = kwargs.pop('timings', False)
5252
self.api_version = kwargs.pop('api_version', None)
5353
self.api_version = self.api_version or api_versions.APIVersion()
54+
55+
if isinstance(self.api_version, str):
56+
self.api_version = api_versions.APIVersion(self.api_version)
57+
58+
api_versions.check_version(self.api_version)
59+
5460
super(SessionClient, self).__init__(*args, **kwargs)
5561

5662
def request(self, url, method, **kwargs):

novaclient/tests/unit/test_api_versions.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,27 @@ def fake_func():
343343
self.assertEqual(expected_name, fake_func.__id__)
344344

345345

346+
class CheckVersionTestCase(utils.TestCase):
347+
def test_version_unsupported(self):
348+
for version in ('1.0', '1.5', '1.100'):
349+
with self.subTest('version too old', version=version):
350+
self.assertRaises(
351+
exceptions.UnsupportedVersion,
352+
api_versions.check_version,
353+
api_versions.APIVersion(version))
354+
355+
for version in ('2.97', '2.101', '3.0'):
356+
with self.subTest('version too new', version=version):
357+
self.assertRaises(
358+
exceptions.UnsupportedVersion,
359+
api_versions.check_version,
360+
api_versions.APIVersion(version))
361+
362+
for version in ('2.1', '2.57', '2.96'):
363+
with self.subTest('version just right', version=version):
364+
api_versions.check_version(api_versions.APIVersion(version))
365+
366+
346367
class DiscoverVersionTestCase(utils.TestCase):
347368
def setUp(self):
348369
super(DiscoverVersionTestCase, self).setUp()

0 commit comments

Comments
 (0)