Merge "Remove the dependency on oslo.config"
This commit is contained in:
@@ -14,7 +14,6 @@
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
from oslo.config import cfg
|
||||
import six
|
||||
|
||||
from marconiclient.auth import base
|
||||
@@ -34,18 +33,18 @@ if keystone:
|
||||
_BACKENDS['keystone'] = keystone.KeystoneAuth
|
||||
|
||||
|
||||
def _register_opts(conf):
|
||||
"""Registers auth cli options.
|
||||
def get_backend(backend='noauth', options=None):
|
||||
"""Loads backend `auth_backend`
|
||||
|
||||
This function exists mostly for testing
|
||||
purposes.
|
||||
:params backend: The backend name to load.
|
||||
Default: `noauth`
|
||||
:type backend: `six.string_types`
|
||||
:param options: Options to pass to the Auth
|
||||
backend. Refer to the backend for more info.
|
||||
:type options: `dict`
|
||||
"""
|
||||
backend_opt = cfg.StrOpt('auth_backend', default='noauth',
|
||||
help='Backend plugin to use for authentication')
|
||||
conf.register_cli_opt(backend_opt)
|
||||
if options is None:
|
||||
options = {}
|
||||
|
||||
|
||||
def get_backend(conf):
|
||||
_register_opts(conf)
|
||||
backend = _BACKENDS[conf.auth_backend](conf)
|
||||
backend = _BACKENDS[backend](options)
|
||||
return backend
|
||||
|
||||
@@ -13,55 +13,31 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from oslo.config import cfg
|
||||
|
||||
from keystoneclient.v2_0 import client as ksclient
|
||||
|
||||
from marconiclient.auth import base
|
||||
from marconiclient.common import utils
|
||||
|
||||
|
||||
# NOTE(flaper87): Some of the code below
|
||||
# was brought to you by the very unique
|
||||
# work of ceilometerclient.
|
||||
class KeystoneAuth(base.AuthBackend):
|
||||
"""Keystone Auth backend
|
||||
|
||||
_CLI_OPTIONS = [
|
||||
cfg.StrOpt("os_username", default=utils.env('OS_USERNAME'),
|
||||
help='Defaults to env[OS_USERNAME]'),
|
||||
|
||||
cfg.StrOpt("os_password", default=utils.env('OS_PASSWORD'),
|
||||
help='Defaults to env[OS_PASSWORD]'),
|
||||
|
||||
cfg.StrOpt("os_project_id", default=utils.env('OS_PROJECT_ID'),
|
||||
help='Defaults to env[OS_PROJECT_ID]'),
|
||||
|
||||
cfg.StrOpt("os_project_name", default=utils.env('OS_PROJECT_NAME'),
|
||||
help='Defaults to env[OS_PROJECT_NAME]'),
|
||||
|
||||
cfg.StrOpt("os_auth_url", default=utils.env('OS_AUTH_URL'),
|
||||
help='Defaults to env[OS_AUTH_URL]'),
|
||||
|
||||
cfg.StrOpt("os_auth_token", default=utils.env('OS_AUTH_TOKEN'),
|
||||
help='Defaults to env[OS_AUTH_TOKEN]'),
|
||||
|
||||
cfg.StrOpt("os_region_name", default=utils.env('OS_REGION_NAME'),
|
||||
help='Defaults to env[OS_REGION_NAME]'),
|
||||
|
||||
cfg.StrOpt("os_service_type", default=utils.env('OS_SERVICE_TYPE'),
|
||||
help='Defaults to env[OS_SERVICE_TYPE]'),
|
||||
|
||||
cfg.StrOpt("os_service_type", default=utils.env('OS_SERVICE_TYPE'),
|
||||
help='Defaults to env[OS_SERVICE_TYPE]'),
|
||||
|
||||
cfg.StrOpt("os_endpoint_type", default=utils.env('OS_ENDPOINT_TYPE'),
|
||||
help='Defaults to env[OS_ENDPOINT_TYPE]'),
|
||||
|
||||
]
|
||||
|
||||
def __init__(self, conf):
|
||||
super(KeystoneAuth, self).__init__(conf)
|
||||
conf.register_cli_opts(self._CLI_OPTIONS)
|
||||
:params conf: A dictionary with Keystone's
|
||||
custom parameters:
|
||||
- os_username
|
||||
- os_password
|
||||
- os_project_id
|
||||
- os_project_name
|
||||
- os_auth_url
|
||||
- os_auth_token
|
||||
- os_region_name
|
||||
- os_service_type
|
||||
- os_service_type
|
||||
- os_endpoint_type
|
||||
:type conf: `dict`
|
||||
"""
|
||||
|
||||
def _get_ksclient(self, **kwargs):
|
||||
"""Get an endpoint and auth token from Keystone.
|
||||
@@ -73,18 +49,11 @@ class KeystoneAuth(base.AuthBackend):
|
||||
* insecure: allow insecure SSL (no cert verification)
|
||||
* project_{name|id}: name or ID of project
|
||||
"""
|
||||
return ksclient.Client(username=self.conf.os_username,
|
||||
password=self.conf.os_password,
|
||||
tenant_id=self.conf.os_project_id,
|
||||
tenant_name=self.conf.os_project_name,
|
||||
auth_url=self.conf.os_auth_url,
|
||||
insecure=self.conf.insecure)
|
||||
return ksclient.Client(**kwargs)
|
||||
|
||||
def _get_endpoint(self, client):
|
||||
def _get_endpoint(self, client, **extra):
|
||||
"""Get an endpoint using the provided keystone client."""
|
||||
return client.service_catalog.url_for(
|
||||
service_type=self.conf.service_type or 'queuing',
|
||||
endpoint_type=self.conf.endpoint_type or 'publicURL')
|
||||
return client.service_catalog.url_for(**extra)
|
||||
|
||||
def authenticate(self, api_version, request):
|
||||
"""Get an authtenticated client, based on the credentials
|
||||
@@ -95,21 +64,19 @@ class KeystoneAuth(base.AuthBackend):
|
||||
the auth information.
|
||||
"""
|
||||
|
||||
token = self.conf.os_auth_token
|
||||
if not self.conf.os_auth_token or not request.endpoint:
|
||||
token = self.conf.get('os_auth_token')
|
||||
if not token or not request.endpoint:
|
||||
# NOTE(flaper87): Lets assume all the
|
||||
# required information was provided
|
||||
# either through env variables or CLI
|
||||
# params. Let keystoneclient fail otherwise.
|
||||
ks_kwargs = {
|
||||
'username': self.conf.os_username,
|
||||
'password': self.conf.os_password,
|
||||
'tenant_id': self.conf.os_project_id,
|
||||
'tenant_name': self.conf.os_project_name,
|
||||
'auth_url': self.conf.os_auth_url,
|
||||
'service_type': self.conf.os_service_type,
|
||||
'endpoint_type': self.conf.os_endpoint_type,
|
||||
'insecure': self.conf.insecure,
|
||||
'username': self.conf.get('os_username'),
|
||||
'password': self.conf.get('os_password'),
|
||||
'tenant_id': self.conf.get('os_project_id'),
|
||||
'tenant_name': self.conf.get('os_project_name'),
|
||||
'auth_url': self.conf.get('os_auth_url'),
|
||||
'insecure': self.conf.get('insecure'),
|
||||
}
|
||||
|
||||
_ksclient = self._get_ksclient(**ks_kwargs)
|
||||
@@ -118,7 +85,13 @@ class KeystoneAuth(base.AuthBackend):
|
||||
token = _ksclient.auth_token
|
||||
|
||||
if not request.endpoint:
|
||||
request.endpoint = self._get_endpoint(_ksclient, **ks_kwargs)
|
||||
extra = {
|
||||
'service_type': self.conf.get('os_service_type',
|
||||
'queuing'),
|
||||
'endpoint_type': self.conf.get('os_endpoint_type',
|
||||
'publicURL'),
|
||||
}
|
||||
request.endpoint = self._get_endpoint(_ksclient, **extra)
|
||||
|
||||
# NOTE(flaper87): Update the request spec
|
||||
# with the final token.
|
||||
|
||||
@@ -15,40 +15,39 @@
|
||||
|
||||
import uuid
|
||||
|
||||
from oslo.config import cfg
|
||||
|
||||
from marconiclient.queues.v1 import queues
|
||||
from marconiclient import transport
|
||||
|
||||
|
||||
_CLIENT_OPTIONS = [
|
||||
cfg.StrOpt('os_queues_url',
|
||||
help='Queues remote URL'),
|
||||
|
||||
cfg.StrOpt('client_uuid',
|
||||
default=uuid.uuid4().hex,
|
||||
help='Client UUID'),
|
||||
]
|
||||
|
||||
|
||||
class Client(object):
|
||||
"""Client base class
|
||||
|
||||
def __init__(self, conf, url=None, version=1):
|
||||
self.conf = conf
|
||||
:param url: Marconi's instance base url.
|
||||
:type url: `six.text_type`
|
||||
:param version: API Version pointing to.
|
||||
:type version: `int`
|
||||
:param options: Extra options:
|
||||
- client_uuid: Custom client uuid. A new one
|
||||
will be generated, if not passed.
|
||||
- auth_opts: Authentication options:
|
||||
- backend
|
||||
- options
|
||||
:type options: `dict`
|
||||
"""
|
||||
|
||||
# NOTE(flaper87): This won't actually register
|
||||
# the CLI options until the class is instantiated
|
||||
# which is dumb. It'll refactored when the CLI API
|
||||
# work starts.
|
||||
self.conf.register_cli_opts(_CLIENT_OPTIONS)
|
||||
self.api_url = self.conf.os_queues_url or url
|
||||
def __init__(self, url=None, version=1, conf=None):
|
||||
self.conf = conf or {}
|
||||
|
||||
self.api_url = url
|
||||
self.api_version = version
|
||||
|
||||
self.client_uuid = self.conf.client_uuid
|
||||
self.auth_opts = self.conf.get('auth_opts', {})
|
||||
self.client_uuid = self.conf.get('client_uuid',
|
||||
uuid.uuid4().hex)
|
||||
|
||||
def transport(self):
|
||||
"""Gets a transport based on conf."""
|
||||
return transport.get_transport_for_conf(self.conf)
|
||||
"""Gets a transport based the api url and version."""
|
||||
return transport.get_transport_for(self.url,
|
||||
self.api_version)
|
||||
|
||||
def queue(self, ref, **kwargs):
|
||||
"""Returns a queue instance
|
||||
|
||||
@@ -43,12 +43,13 @@ class Queue(object):
|
||||
:type request: `transport.request.Request`
|
||||
"""
|
||||
|
||||
trans = transport.get_transport_for(self.client.conf, request)
|
||||
trans = transport.get_transport_for(request,
|
||||
options=self.client.conf)
|
||||
return (trans or self.client.transport)
|
||||
|
||||
def _request_and_transport(self):
|
||||
api = 'queues.v' + str(self.client.api_version)
|
||||
req = request.prepare_request(self.client.conf,
|
||||
req = request.prepare_request(self.client.auth_opts,
|
||||
endpoint=self.client.api_url,
|
||||
api=api)
|
||||
|
||||
|
||||
@@ -16,15 +16,13 @@
|
||||
import fixtures
|
||||
import testtools
|
||||
|
||||
from oslo.config import cfg
|
||||
|
||||
|
||||
class TestBase(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestBase, self).setUp()
|
||||
|
||||
self.conf = cfg.ConfigOpts()
|
||||
self.conf = {}
|
||||
self.useFixture(fixtures.FakeLogger('marconi'))
|
||||
|
||||
# NOTE(kgriffs): Don't monkey-patch stdout since it breaks
|
||||
@@ -40,9 +38,7 @@ class TestBase(testtools.TestCase):
|
||||
|
||||
If a group argument is supplied, the overrides are applied to
|
||||
the specified configuration option group.
|
||||
|
||||
All overrides are automatically cleared at the end of the current
|
||||
test by the tearDown() method.
|
||||
"""
|
||||
for k, v in kw.items():
|
||||
self.conf.set_override(k, v, group)
|
||||
parent = (group and self.conf.setdefault(group, {})
|
||||
or self.conf)
|
||||
parent.update(kw)
|
||||
|
||||
@@ -42,8 +42,8 @@ class QueuesV1QueueTestBase(base.TestBase):
|
||||
super(QueuesV1QueueTestBase, self).setUp()
|
||||
self.transport = self.transport_cls(self.conf)
|
||||
|
||||
self.client = client.Client(self.conf, self.url,
|
||||
self.version)
|
||||
self.client = client.Client(self.url, self.version,
|
||||
self.conf)
|
||||
|
||||
# NOTE(flaper87): Nasty monkeypatch, lets use
|
||||
# the dummy transport here.
|
||||
|
||||
@@ -13,29 +13,21 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from oslo.config import cfg
|
||||
import six
|
||||
from six.moves.urllib import parse
|
||||
from stevedore import driver
|
||||
|
||||
from marconiclient import errors as _errors
|
||||
|
||||
_TRANSPORT_OPTIONS = [
|
||||
cfg.StrOpt('default_transport', default='http',
|
||||
help='Transport to use as default'),
|
||||
cfg.IntOpt('default_transport_version', default=1,
|
||||
help='Transport to use as default'),
|
||||
]
|
||||
|
||||
|
||||
def get_transport(conf, transport, version=1):
|
||||
def get_transport(transport='http', version=1, options=None):
|
||||
"""Gets a transport and returns it.
|
||||
|
||||
:param conf: the user configuration
|
||||
:type conf: cfg.ConfigOpts
|
||||
:param transport: Transport name
|
||||
:param transport: Transport name.
|
||||
Default: http
|
||||
:type transport: `six.string_types`
|
||||
:param version: Version of the target transport.
|
||||
Default: 1
|
||||
:type version: int
|
||||
|
||||
:returns: A `Transport` instance.
|
||||
@@ -49,36 +41,20 @@ def get_transport(conf, transport, version=1):
|
||||
mgr = driver.DriverManager(namespace,
|
||||
entry_point,
|
||||
invoke_on_load=True,
|
||||
invoke_args=[conf])
|
||||
invoke_args=[options])
|
||||
except RuntimeError as ex:
|
||||
raise _errors.DriverLoadFailure(entry_point, ex)
|
||||
|
||||
return mgr.driver
|
||||
|
||||
|
||||
def get_transport_for_conf(conf):
|
||||
"""Gets a transport based on the config object
|
||||
|
||||
It'll load a transport based on the `default-transport`
|
||||
and `default-transport-version` params.
|
||||
|
||||
:param conf: the user configuration
|
||||
:type conf: cfg.ConfigOpts
|
||||
"""
|
||||
conf.register_opts(_TRANSPORT_OPTIONS)
|
||||
return get_transport(conf, conf.default_transport,
|
||||
conf.default_transport_version)
|
||||
|
||||
|
||||
def get_transport_for(conf, url_or_request, version=1):
|
||||
def get_transport_for(url_or_request, version=1, options=None):
|
||||
"""Gets a transport for a given url.
|
||||
|
||||
An example transport URL might be::
|
||||
|
||||
zmq://example.org:8888/v1/
|
||||
|
||||
:param conf: the user configuration
|
||||
:type conf: cfg.ConfigOpts
|
||||
:param url_or_request: a transport URL
|
||||
:type url_or_request: `six.string_types` or
|
||||
`marconiclient.transport.request.Request`
|
||||
@@ -94,4 +70,4 @@ def get_transport_for(conf, url_or_request, version=1):
|
||||
url = url_or_request.endpoint
|
||||
|
||||
parsed = parse.urlparse(url)
|
||||
return get_transport(conf, parsed.scheme, version)
|
||||
return get_transport(parsed.scheme, version, options)
|
||||
|
||||
@@ -21,8 +21,8 @@ import six
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class Transport(object):
|
||||
|
||||
def __init__(self, conf):
|
||||
self.conf = conf
|
||||
def __init__(self, options):
|
||||
self.options = options
|
||||
|
||||
@abc.abstractmethod
|
||||
def send(self, request):
|
||||
|
||||
@@ -32,8 +32,8 @@ class HttpTransport(base.Transport):
|
||||
404: errors.ResourceNotFound,
|
||||
}
|
||||
|
||||
def __init__(self, conf):
|
||||
super(HttpTransport, self).__init__(conf)
|
||||
def __init__(self, options):
|
||||
super(HttpTransport, self).__init__(options)
|
||||
self.client = http.Client()
|
||||
|
||||
def _prepare(self, request):
|
||||
|
||||
@@ -21,7 +21,7 @@ from marconiclient import auth
|
||||
from marconiclient import errors
|
||||
|
||||
|
||||
def prepare_request(conf, data=None, **kwargs):
|
||||
def prepare_request(auth_opts=None, data=None, **kwargs):
|
||||
"""Prepares a request
|
||||
|
||||
This method takes care of authentication
|
||||
@@ -30,8 +30,8 @@ def prepare_request(conf, data=None, **kwargs):
|
||||
The request returned by this call is ready to
|
||||
be sent to the server.
|
||||
|
||||
:param conf: `cfg.ConfigOpts` instance to use.
|
||||
:type conf: `cfg.ConfigOpts`
|
||||
:param auth_opts: Auth parameters
|
||||
:type auth_opts: `dict`
|
||||
:param data: Optional data to send along with the
|
||||
request. If data is not None, it'll be serialized.
|
||||
:type data: Any primitive type that is json-serializable.
|
||||
@@ -42,7 +42,7 @@ def prepare_request(conf, data=None, **kwargs):
|
||||
"""
|
||||
|
||||
req = Request(**kwargs)
|
||||
auth_backend = auth.get_backend(conf)
|
||||
auth_backend = auth.get_backend(**(auth_opts or {}))
|
||||
# TODO(flaper87): Do something smarter
|
||||
# to get the api_version.
|
||||
req = auth_backend.authenticate(1, req)
|
||||
|
||||
@@ -21,16 +21,13 @@ class TestBaseAuth(base.TestBase):
|
||||
|
||||
def test_get_backend(self):
|
||||
try:
|
||||
auth.get_backend(self.conf)
|
||||
auth.get_backend(options=self.conf)
|
||||
except KeyError:
|
||||
self.fail("Test failed")
|
||||
|
||||
def test_get_non_existing_backend(self):
|
||||
auth._register_opts(self.conf)
|
||||
self.config(auth_backend="not_existing")
|
||||
|
||||
try:
|
||||
auth.get_backend(self.conf)
|
||||
auth.get_backend('not_existing')
|
||||
self.fail("Test failed")
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
|
||||
|
||||
import mock
|
||||
from oslo.config import cfg
|
||||
|
||||
try:
|
||||
from keystoneclient.v2_0 import client as ksclient
|
||||
@@ -42,13 +41,8 @@ class TestKeystoneAuth(base.TestBase):
|
||||
if not ksclient:
|
||||
self.skipTest('Keystone client is not installed')
|
||||
|
||||
auth._register_opts(self.conf)
|
||||
self.config(auth_backend='keystone')
|
||||
self.auth = auth.get_backend(self.conf)
|
||||
|
||||
# FIXME(flaper87): Remove once insecure is added
|
||||
# in the right place.
|
||||
self.conf.register_opt(cfg.BoolOpt('insecure', default=False))
|
||||
self.auth = auth.get_backend(backend='keystone',
|
||||
options=self.conf)
|
||||
|
||||
def test_no_token(self):
|
||||
test_endpoint = 'http://example.org:8888'
|
||||
|
||||
Reference in New Issue
Block a user