Enable ironicclient with --ironic-api-version 1.x
python-ironic-client doesn't recognize API micro-version parameter. Reuse --ironic-api-version to recognize this. 1. The client accepts '1.x' or 'latest' as valid API version and send corresponding headers to Ironic. 2. If the user does not specify a version, client will not sent any extra headers to Ironic. It will use the minimum version. Closes-Bug: #1417430 Change-Id: I1db6e2f4e57d6d47d86f068018f143d0044b7211
This commit is contained in:
parent
17018ce723
commit
53095aaa8f
@ -111,6 +111,7 @@ def get_client(api_version, **kwargs):
|
||||
'cert_file': kwargs.get('cert_file'),
|
||||
'key_file': kwargs.get('key_file'),
|
||||
'auth_ref': auth_ref,
|
||||
'os_ironic_api_version': kwargs.get('os_ironic_api_version'),
|
||||
}
|
||||
|
||||
return Client(api_version, endpoint, **cli_kwargs)
|
||||
|
@ -62,6 +62,7 @@ class HTTPClient(object):
|
||||
self.endpoint_trimmed = _trim_endpoint_api_version(endpoint)
|
||||
self.auth_token = kwargs.get('token')
|
||||
self.auth_ref = kwargs.get('auth_ref')
|
||||
self.os_ironic_api_version = kwargs.get('os_ironic_api_version')
|
||||
self.connection_params = self.get_connection_params(endpoint, **kwargs)
|
||||
|
||||
@staticmethod
|
||||
@ -146,6 +147,9 @@ class HTTPClient(object):
|
||||
# Copy the kwargs so we can reuse the original in case of redirects
|
||||
kwargs['headers'] = copy.deepcopy(kwargs.get('headers', {}))
|
||||
kwargs['headers'].setdefault('User-Agent', USER_AGENT)
|
||||
if self.os_ironic_api_version:
|
||||
kwargs['headers'].setdefault('X-OpenStack-Ironic-API-Version',
|
||||
self.os_ironic_api_version)
|
||||
if self.auth_token:
|
||||
kwargs['headers'].setdefault('X-Auth-Token', self.auth_token)
|
||||
|
||||
@ -293,6 +297,9 @@ class SessionClient(adapter.LegacyJsonAdapter):
|
||||
def _http_request(self, url, method, **kwargs):
|
||||
kwargs.setdefault('user_agent', USER_AGENT)
|
||||
kwargs.setdefault('auth', self.auth)
|
||||
if getattr(self, 'os_ironic_api_version', None):
|
||||
kwargs['headers'].setdefault('X-OpenStack-Ironic-API-Version',
|
||||
self.os_ironic_api_version)
|
||||
|
||||
endpoint_filter = kwargs.setdefault('endpoint_filter', {})
|
||||
endpoint_filter.setdefault('interface', self.interface)
|
||||
@ -301,7 +308,6 @@ class SessionClient(adapter.LegacyJsonAdapter):
|
||||
|
||||
resp = self.session.request(url, method,
|
||||
raise_exc=False, **kwargs)
|
||||
|
||||
if 400 <= resp.status_code < 600:
|
||||
error_json = _extract_error_json(resp.content)
|
||||
raise exc.from_response(resp, error_json.get('faultstring'),
|
||||
@ -371,12 +377,16 @@ def _construct_http_client(*args, **kwargs):
|
||||
service_type = kwargs.pop('service_type', 'baremetal')
|
||||
interface = kwargs.pop('endpoint_type', None)
|
||||
region_name = kwargs.pop('region_name', None)
|
||||
return SessionClient(session=session,
|
||||
auth=auth,
|
||||
interface=interface,
|
||||
service_type=service_type,
|
||||
region_name=region_name,
|
||||
service_name=None,
|
||||
user_agent='python-ironicclient')
|
||||
os_ironic_api_version = kwargs.pop('os_ironic_api_version', None)
|
||||
session_client = SessionClient(session=session,
|
||||
auth=auth,
|
||||
interface=interface,
|
||||
service_type=service_type,
|
||||
region_name=region_name,
|
||||
service_name=None,
|
||||
user_agent='python-ironicclient')
|
||||
# Append an ironic specific variable to session
|
||||
session_client.os_ironic_api_version = os_ironic_api_version
|
||||
return session_client
|
||||
else:
|
||||
return HTTPClient(*args, **kwargs)
|
||||
|
@ -42,6 +42,9 @@ from ironicclient.openstack.common import gettextutils
|
||||
gettextutils.install('ironicclient')
|
||||
|
||||
|
||||
LATEST_API_VERSION = ('1', 'latest')
|
||||
|
||||
|
||||
class IronicShell(object):
|
||||
|
||||
def _append_global_identity_args(self, parser):
|
||||
@ -187,8 +190,9 @@ class IronicShell(object):
|
||||
parser.add_argument('--ironic-api-version',
|
||||
default=cliutils.env(
|
||||
'IRONIC_API_VERSION', default='1'),
|
||||
help='Defaults to env[IRONIC_API_VERSION] '
|
||||
'or 1')
|
||||
help='Accepts 1.x (where "x" is microversion) '
|
||||
'or "latest", Defaults to '
|
||||
'env[IRONIC_API_VERSION] or 1')
|
||||
|
||||
parser.add_argument('--ironic_api_version',
|
||||
help=argparse.SUPPRESS)
|
||||
@ -349,6 +353,30 @@ class IronicShell(object):
|
||||
|
||||
return auth
|
||||
|
||||
def _check_version(self, api_version):
|
||||
if api_version == 'latest':
|
||||
return LATEST_API_VERSION
|
||||
else:
|
||||
try:
|
||||
versions = tuple(int(i) for i in api_version.split('.'))
|
||||
except ValueError:
|
||||
versions = ()
|
||||
if len(versions) == 1:
|
||||
# Default value of ironic_api_version is '1'.
|
||||
# If user not specify the value of api version, not passing
|
||||
# headers at all.
|
||||
os_ironic_api_version = None
|
||||
elif len(versions) == 2:
|
||||
os_ironic_api_version = api_version
|
||||
# In the case of '1.0'
|
||||
if versions[1] == 0:
|
||||
os_ironic_api_version = None
|
||||
else:
|
||||
raise exc.CommandError("Incorrect API version %s, expect "
|
||||
"value ike X.Y" % api_version)
|
||||
api_major_version = versions[0]
|
||||
return (api_major_version, os_ironic_api_version)
|
||||
|
||||
def main(self, argv):
|
||||
# Parse args once to find version
|
||||
parser = self.get_base_parser()
|
||||
@ -356,8 +384,10 @@ class IronicShell(object):
|
||||
self._setup_debugging(options.debug)
|
||||
|
||||
# build available subcommands based on version
|
||||
api_version = options.ironic_api_version
|
||||
subcommand_parser = self.get_subcommand_parser(api_version)
|
||||
(api_major_version, os_ironic_api_version) = (
|
||||
self._check_version(options.ironic_api_version))
|
||||
|
||||
subcommand_parser = self.get_subcommand_parser(api_major_version)
|
||||
self.parser = subcommand_parser
|
||||
|
||||
# Handle top-level --help/-h before attempting to parse
|
||||
@ -466,7 +496,8 @@ class IronicShell(object):
|
||||
'username': args.os_username,
|
||||
'password': args.os_password,
|
||||
}
|
||||
client = iroclient.Client(api_version, endpoint, **kwargs)
|
||||
kwargs['os_ironic_api_version'] = os_ironic_api_version
|
||||
client = iroclient.Client(api_major_version, endpoint, **kwargs)
|
||||
|
||||
try:
|
||||
args.func(client, args)
|
||||
|
@ -140,3 +140,18 @@ class ClientTest(utils.BaseTestCase):
|
||||
client = get_client('1', **kwargs)
|
||||
|
||||
self.assertEqual(ksclient().auth_ref, client.http_client.auth_ref)
|
||||
|
||||
def test_get_client_with_api_version(self):
|
||||
self.useFixture(fixtures.MonkeyPatch(
|
||||
'ironicclient.client._get_ksclient', fake_get_ksclient))
|
||||
kwargs = {
|
||||
'os_tenant_name': 'TENANT_NAME',
|
||||
'os_username': 'USERNAME',
|
||||
'os_password': 'PASSWORD',
|
||||
'os_auth_url': 'http://localhost:35357/v2.0',
|
||||
'os_auth_token': '',
|
||||
'os_ironic_api_version': 'latest',
|
||||
}
|
||||
client = get_client('1', **kwargs)
|
||||
|
||||
self.assertEqual('latest', client.http_client.os_ironic_api_version)
|
||||
|
@ -170,6 +170,12 @@ class ShellTest(utils.BaseTestCase):
|
||||
self.assertThat(stdout,
|
||||
matchers.MatchesRegex(r, self.re_options))
|
||||
|
||||
def test_ironic_api_version(self):
|
||||
self.shell('--ironic-api-version 1.2 help')
|
||||
self.shell('--ironic-api-version latest help')
|
||||
self.assertRaises(exc.CommandError,
|
||||
self.shell, '--ironic-api-version 1.2.1 help')
|
||||
|
||||
|
||||
class TestCase(testtools.TestCase):
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user