Try to fetch inspector URL from the service catalog
Change-Id: I710a2dc8dea3ad6b8a9bb2e4aac9225658dd8d1d Closes-Bug: #1391865
This commit is contained in:
parent
1709ba6bd6
commit
81bfb6d550
27
README.rst
27
README.rst
@ -17,14 +17,16 @@ Python API
|
||||
To use Python API first create a ``ClientV1`` object::
|
||||
|
||||
import ironic_inspector_client
|
||||
|
||||
url = 'http://HOST:5050'
|
||||
client = ironic_inspector_client.ClientV1(session=keystone_session,
|
||||
inspector_url=url)
|
||||
client = ironic_inspector_client.ClientV1(session=keystone_session)
|
||||
|
||||
This code creates a client with API version *1.0* and a given Keystone session.
|
||||
If ``inspector_url`` is missing, local host is assumed for now. Service
|
||||
catalog will be used in the future.
|
||||
The service URL is fetched from the service catalog in this case. Optional
|
||||
arguments ``service_type``, ``interface`` and ``region_name`` can be provided
|
||||
to modify how the URL is looked up.
|
||||
|
||||
If the catalog lookup fails, the local host with port 5050 is tried. However,
|
||||
this behaviour is deprecated and should not be relied on.
|
||||
Also an explicit ``inspector_url`` can be passed to bypass service catalog.
|
||||
|
||||
Optional ``api_version`` argument is a minimum API version that a server must
|
||||
support. It can be a tuple (MAJ, MIN), string "MAJ.MIN" or integer
|
||||
@ -201,19 +203,20 @@ functionality:
|
||||
|
||||
* Starting introspection::
|
||||
|
||||
ironic_inspector_client.introspect(uuid[, new_ipmi_password[, new_ipmi_username]][, base_url][, api_version][, session])
|
||||
ironic_inspector_client.introspect(uuid[, new_ipmi_password[, new_ipmi_username]][, base_url][, api_version] **)
|
||||
|
||||
* Getting introspection status::
|
||||
|
||||
ironic_inspector_client.get_status(uuid[, base_url][, api_version[, session]])
|
||||
ironic_inspector_client.get_status(uuid[, base_url][, api_version] **)
|
||||
|
||||
* Getting API versions supported by a server::
|
||||
|
||||
ironic_inspector_client.server_api_versions([base_url][, session])
|
||||
ironic_inspector_client.server_api_versions([base_url] **)
|
||||
|
||||
Here ``base_url`` argument is the same as ``inspector_url`` argument to
|
||||
``ClientV1`` constructor. The first 2 functions also accept deprecated
|
||||
``auth_token`` argument, which should not be used.
|
||||
Here ``base_url`` argument is the same as ``inspector_url`` argument
|
||||
to the ``ClientV1`` constructor. Keyword arguments are passed to the client
|
||||
constructor intact. The first 2 functions also accept deprecated ``auth_token``
|
||||
argument, which should not be used.
|
||||
|
||||
|
||||
.. _Gerrit Workflow: http://docs.openstack.org/infra/manual/developers.html#development-workflow
|
||||
|
@ -28,7 +28,7 @@ VersionNotSupported = http.VersionNotSupported
|
||||
|
||||
def introspect(uuid, base_url=None, auth_token=None,
|
||||
new_ipmi_password=None, new_ipmi_username=None,
|
||||
api_version=DEFAULT_API_VERSION, session=None):
|
||||
api_version=DEFAULT_API_VERSION, session=None, **kwargs):
|
||||
"""Start introspection for a node.
|
||||
|
||||
:param uuid: node uuid
|
||||
@ -43,18 +43,19 @@ def introspect(uuid, base_url=None, auth_token=None,
|
||||
:param api_version: requested Ironic Inspector API version, defaults to
|
||||
``DEFAULT_API_VERSION`` attribute.
|
||||
:param session: keystone session.
|
||||
:param kwargs: keyword arguments to pass to the ClientV1 constructor.
|
||||
:raises: ClientError on error reported from a server
|
||||
:raises: VersionNotSupported if requested api_version is not supported
|
||||
:raises: *requests* library exception on connection problems.
|
||||
"""
|
||||
c = v1.ClientV1(api_version=api_version, auth_token=auth_token,
|
||||
inspector_url=base_url, session=session)
|
||||
inspector_url=base_url, session=session, **kwargs)
|
||||
return c.introspect(uuid, new_ipmi_username=new_ipmi_username,
|
||||
new_ipmi_password=new_ipmi_password)
|
||||
|
||||
|
||||
def get_status(uuid, base_url=None, auth_token=None,
|
||||
api_version=DEFAULT_API_VERSION, session=None):
|
||||
api_version=DEFAULT_API_VERSION, session=None, **kwargs):
|
||||
"""Get introspection status for a node.
|
||||
|
||||
New in Ironic Inspector version 1.0.0.
|
||||
@ -65,27 +66,29 @@ def get_status(uuid, base_url=None, auth_token=None,
|
||||
:param api_version: requested Ironic Inspector API version, defaults to
|
||||
``DEFAULT_API_VERSION`` attribute.
|
||||
:param session: keystone session.
|
||||
:param kwargs: keyword arguments to pass to the ClientV1 constructor.
|
||||
:raises: ClientError on error reported from a server
|
||||
:raises: VersionNotSupported if requested api_version is not supported
|
||||
:raises: *requests* library exception on connection problems.
|
||||
"""
|
||||
c = v1.ClientV1(api_version=api_version, auth_token=auth_token,
|
||||
inspector_url=base_url, session=session)
|
||||
inspector_url=base_url, session=session, **kwargs)
|
||||
return c.get_status(uuid)
|
||||
|
||||
|
||||
def server_api_versions(base_url=None, session=None):
|
||||
def server_api_versions(base_url=None, session=None, **kwargs):
|
||||
"""Get minimum and maximum supported API versions from a server.
|
||||
|
||||
:param base_url: *Ironic Inspector* URL in form: http://host:port[/ver],
|
||||
defaults to ``http://<current host>:5050/v1``.
|
||||
:param session: keystone session (authentication is not required).
|
||||
:param kwargs: keyword arguments to pass to the BaseClient constructor.
|
||||
:return: tuple (minimum version, maximum version) each version is returned
|
||||
as a tuple (X, Y)
|
||||
:raises: *requests* library exception on connection problems.
|
||||
:raises: ValueError if returned version cannot be parsed
|
||||
"""
|
||||
c = http.BaseClient(1, inspector_url=base_url, session=session)
|
||||
c = http.BaseClient(1, inspector_url=base_url, session=session, **kwargs)
|
||||
return c.server_api_versions()
|
||||
|
||||
|
||||
|
@ -17,6 +17,7 @@ import json
|
||||
import logging
|
||||
|
||||
from keystoneclient.auth import token_endpoint
|
||||
from keystoneclient import exceptions as ks_exc
|
||||
from keystoneclient import session as ks_session
|
||||
from oslo_utils import netutils
|
||||
import requests
|
||||
@ -84,18 +85,24 @@ class BaseClient(object):
|
||||
"""Base class for clients, provides common HTTP code."""
|
||||
|
||||
def __init__(self, api_version, inspector_url=None, auth_token=None,
|
||||
session=None):
|
||||
session=None, service_type='baremetal-introspection',
|
||||
interface=None, region_name=None):
|
||||
"""Create a client.
|
||||
|
||||
:param api_version: minimum API version that must be supported by
|
||||
the server
|
||||
:param inspector_url: *Ironic Inspector* URL in form:
|
||||
http://host:port[/ver],
|
||||
http://host:port[/ver]. When session is provided, defaults to
|
||||
service URL from the catalog. As a last resort
|
||||
defaults to ``http://<current host>:5050/v<MAJOR>``.
|
||||
:param auth_token: authentication token (deprecated, use session)
|
||||
:param session: existing keystone session
|
||||
:param service_type: service type to use when looking up the URL
|
||||
:param interface: interface type (public, internal, etc) to use when
|
||||
looking up the URL
|
||||
:param region_name: region name to use when looking up the URL
|
||||
"""
|
||||
self._base_url = (inspector_url or _DEFAULT_URL).rstrip('/')
|
||||
self._base_url = inspector_url or _DEFAULT_URL
|
||||
self._auth_token = auth_token
|
||||
|
||||
if session is None:
|
||||
@ -110,7 +117,18 @@ class BaseClient(object):
|
||||
self._session = ks_session.Session(auth)
|
||||
else:
|
||||
self._session = session
|
||||
if not inspector_url:
|
||||
try:
|
||||
self._base_url = session.get_endpoint(
|
||||
service_type=service_type,
|
||||
interface=interface,
|
||||
region_name=region_name) or _DEFAULT_URL
|
||||
except ks_exc.EndpointNotFound:
|
||||
LOG.warning(_LW('Endpoint for service %s was not found, '
|
||||
'falling back to local host on port 5050'),
|
||||
service_type)
|
||||
|
||||
self._base_url = self._base_url.rstrip('/')
|
||||
self._api_version = self._check_api_version(api_version)
|
||||
self._version_str = '%d.%d' % self._api_version
|
||||
ver_postfix = '/v%d' % self._api_version[0]
|
||||
|
@ -43,7 +43,9 @@ def make_client(instance):
|
||||
return ironic_inspector_client.ClientV1(
|
||||
inspector_url=instance.get_configuration().get('inspector_url'),
|
||||
session=instance.session,
|
||||
api_version=instance._api_version[API_NAME])
|
||||
api_version=instance._api_version[API_NAME],
|
||||
interface=instance._interface,
|
||||
region_name=instance._region_name)
|
||||
|
||||
|
||||
def build_option_parser(parser):
|
||||
|
@ -14,6 +14,7 @@
|
||||
import json
|
||||
import unittest
|
||||
|
||||
from keystoneclient import exceptions
|
||||
from keystoneclient import session
|
||||
import mock
|
||||
|
||||
@ -107,6 +108,7 @@ class TestRequest(unittest.TestCase):
|
||||
super(TestRequest, self).setUp()
|
||||
self.headers = {http._VERSION_HEADER: '1.0'}
|
||||
self.session = mock.Mock(spec=session.Session)
|
||||
self.session.get_endpoint.return_value = self.base_url
|
||||
self.req = self.session.request
|
||||
self.req.return_value.status_code = 200
|
||||
|
||||
@ -129,6 +131,31 @@ class TestRequest(unittest.TestCase):
|
||||
self.assertIs(self.req.return_value, res)
|
||||
self.req.assert_called_once_with(self.base_url + '/foo/bar', 'get',
|
||||
raise_exc=False, headers=self.headers)
|
||||
self.session.get_endpoint.assert_called_once_with(
|
||||
service_type='baremetal-introspection',
|
||||
interface=None, region_name=None)
|
||||
|
||||
def test_ok_no_endpoint(self):
|
||||
self.session.get_endpoint.return_value = None
|
||||
res = self.get_client().request('get', '/foo/bar')
|
||||
|
||||
self.assertIs(self.req.return_value, res)
|
||||
self.req.assert_called_once_with(self.base_url + '/foo/bar', 'get',
|
||||
raise_exc=False, headers=self.headers)
|
||||
self.session.get_endpoint.assert_called_once_with(
|
||||
service_type='baremetal-introspection',
|
||||
interface=None, region_name=None)
|
||||
|
||||
def test_ok_endpoint_not_found(self):
|
||||
self.session.get_endpoint.side_effect = exceptions.EndpointNotFound()
|
||||
res = self.get_client().request('get', '/foo/bar')
|
||||
|
||||
self.assertIs(self.req.return_value, res)
|
||||
self.req.assert_called_once_with(self.base_url + '/foo/bar', 'get',
|
||||
raise_exc=False, headers=self.headers)
|
||||
self.session.get_endpoint.assert_called_once_with(
|
||||
service_type='baremetal-introspection',
|
||||
interface=None, region_name=None)
|
||||
|
||||
@mock.patch.object(session.Session, 'request', autospec=True,
|
||||
**{'return_value.status_code': 200})
|
||||
|
6
releasenotes/notes/service-catalog-45466d1cfd330231.yaml
Normal file
6
releasenotes/notes/service-catalog-45466d1cfd330231.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
features:
|
||||
- Inspector service URL can now be fetched from the service catalog.
|
||||
deprecations:
|
||||
- Using default service URL of locahost:5050 is deprecated now. Either use
|
||||
the service catalog or provide an explicit URL.
|
Loading…
Reference in New Issue
Block a user