Merge "Make keystoneclient use an adapter"
This commit is contained in:
@@ -211,13 +211,12 @@ class Manager(object):
|
|||||||
return self.client.delete(url, **kwargs)
|
return self.client.delete(url, **kwargs)
|
||||||
|
|
||||||
def _update(self, url, body=None, response_key=None, method="PUT",
|
def _update(self, url, body=None, response_key=None, method="PUT",
|
||||||
management=True, **kwargs):
|
**kwargs):
|
||||||
methods = {"PUT": self.client.put,
|
methods = {"PUT": self.client.put,
|
||||||
"POST": self.client.post,
|
"POST": self.client.post,
|
||||||
"PATCH": self.client.patch}
|
"PATCH": self.client.patch}
|
||||||
try:
|
try:
|
||||||
resp, body = methods[method](url, body=body,
|
resp, body = methods[method](url, body=body,
|
||||||
management=management,
|
|
||||||
**kwargs)
|
**kwargs)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise exceptions.ClientException(_("Invalid update method: %s")
|
raise exceptions.ClientException(_("Invalid update method: %s")
|
||||||
|
@@ -52,10 +52,11 @@ if not hasattr(urlparse, 'parse_qsl'):
|
|||||||
|
|
||||||
|
|
||||||
from keystoneclient import access
|
from keystoneclient import access
|
||||||
|
from keystoneclient import adapter
|
||||||
from keystoneclient.auth import base
|
from keystoneclient.auth import base
|
||||||
from keystoneclient import baseclient
|
from keystoneclient import baseclient
|
||||||
from keystoneclient import exceptions
|
from keystoneclient import exceptions
|
||||||
from keystoneclient.i18n import _, _LI, _LW
|
from keystoneclient.i18n import _, _LW
|
||||||
from keystoneclient import session as client_session
|
from keystoneclient import session as client_session
|
||||||
from keystoneclient import utils
|
from keystoneclient import utils
|
||||||
|
|
||||||
@@ -84,6 +85,51 @@ class _FakeRequestSession(object):
|
|||||||
return requests.request(*args, **kwargs)
|
return requests.request(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class _KeystoneAdapter(adapter.LegacyJsonAdapter):
|
||||||
|
"""A wrapper layer to interface keystoneclient with a session.
|
||||||
|
|
||||||
|
An adapter provides a generic interface between a client and the session to
|
||||||
|
provide client specific defaults. This object is passed to the managers.
|
||||||
|
Keystoneclient managers have some additional requirements of variables that
|
||||||
|
they expect to be present on the passed object.
|
||||||
|
|
||||||
|
Subclass the existing adapter to provide those values that keystoneclient
|
||||||
|
managers expect.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def user_id(self):
|
||||||
|
"""Best effort to retrieve the user_id from the plugin.
|
||||||
|
|
||||||
|
Some managers rely on being able to get the currently authenticated
|
||||||
|
user id. This is a problem when we are trying to abstract away the
|
||||||
|
details of an auth plugin.
|
||||||
|
|
||||||
|
For example changing a user's password can require access to the
|
||||||
|
currently authenticated user_id.
|
||||||
|
|
||||||
|
Perform a best attempt to fetch this data. It will work in the legacy
|
||||||
|
case and with identity plugins and be None otherwise which is the same
|
||||||
|
as the historical behavior.
|
||||||
|
"""
|
||||||
|
# the identity plugin case
|
||||||
|
try:
|
||||||
|
return self.session.auth.get_access(self.session).user_id
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# there is a case that we explicity allow (tested by our unit tests)
|
||||||
|
# that says you should be able to set the user_id on a legacy client
|
||||||
|
# and it should overwrite the one retrieved via authentication. If it's
|
||||||
|
# a legacy then self.session.auth is a client and we retrieve user_id.
|
||||||
|
try:
|
||||||
|
return self.session.auth.user_id
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
class HTTPClient(baseclient.Client, base.BaseAuthPlugin):
|
class HTTPClient(baseclient.Client, base.BaseAuthPlugin):
|
||||||
|
|
||||||
version = None
|
version = None
|
||||||
@@ -169,7 +215,6 @@ class HTTPClient(baseclient.Client, base.BaseAuthPlugin):
|
|||||||
self.project_domain_id = None
|
self.project_domain_id = None
|
||||||
self.project_domain_name = None
|
self.project_domain_name = None
|
||||||
|
|
||||||
self.region_name = None
|
|
||||||
self.auth_url = None
|
self.auth_url = None
|
||||||
self._endpoint = None
|
self._endpoint = None
|
||||||
self._management_url = None
|
self._management_url = None
|
||||||
@@ -193,8 +238,8 @@ class HTTPClient(baseclient.Client, base.BaseAuthPlugin):
|
|||||||
self._management_url = self.auth_ref.management_url[0]
|
self._management_url = self.auth_ref.management_url[0]
|
||||||
self.auth_token_from_user = self.auth_ref.auth_token
|
self.auth_token_from_user = self.auth_ref.auth_token
|
||||||
self.trust_id = self.auth_ref.trust_id
|
self.trust_id = self.auth_ref.trust_id
|
||||||
if self.auth_ref.has_service_catalog():
|
if self.auth_ref.has_service_catalog() and not region_name:
|
||||||
self.region_name = self.auth_ref.service_catalog.region_name
|
region_name = self.auth_ref.service_catalog.region_name
|
||||||
else:
|
else:
|
||||||
self.auth_ref = None
|
self.auth_ref = None
|
||||||
|
|
||||||
@@ -251,8 +296,6 @@ class HTTPClient(baseclient.Client, base.BaseAuthPlugin):
|
|||||||
self.auth_token_from_user = None
|
self.auth_token_from_user = None
|
||||||
if endpoint:
|
if endpoint:
|
||||||
self._endpoint = endpoint.rstrip('/')
|
self._endpoint = endpoint.rstrip('/')
|
||||||
if region_name:
|
|
||||||
self.region_name = region_name
|
|
||||||
self._auth_token = None
|
self._auth_token = None
|
||||||
|
|
||||||
if not session:
|
if not session:
|
||||||
@@ -264,6 +307,12 @@ class HTTPClient(baseclient.Client, base.BaseAuthPlugin):
|
|||||||
self.domain = ''
|
self.domain = ''
|
||||||
self.debug_log = debug
|
self.debug_log = debug
|
||||||
|
|
||||||
|
self._adapter = _KeystoneAdapter(session,
|
||||||
|
service_type='identity',
|
||||||
|
interface='admin',
|
||||||
|
region_name=region_name,
|
||||||
|
version=self.version)
|
||||||
|
|
||||||
# keyring setup
|
# keyring setup
|
||||||
if use_keyring and keyring is None:
|
if use_keyring and keyring is None:
|
||||||
_logger.warning(_LW('Failed to load keyring modules.'))
|
_logger.warning(_LW('Failed to load keyring modules.'))
|
||||||
@@ -396,7 +445,7 @@ class HTTPClient(baseclient.Client, base.BaseAuthPlugin):
|
|||||||
project_domain_name = project_domain_name or self.project_domain_name
|
project_domain_name = project_domain_name or self.project_domain_name
|
||||||
|
|
||||||
trust_id = trust_id or self.trust_id
|
trust_id = trust_id or self.trust_id
|
||||||
region_name = region_name or self.region_name
|
region_name = region_name or self._adapter.region_name
|
||||||
|
|
||||||
if not token:
|
if not token:
|
||||||
token = self.auth_token_from_user
|
token = self.auth_token_from_user
|
||||||
@@ -569,83 +618,110 @@ class HTTPClient(baseclient.Client, base.BaseAuthPlugin):
|
|||||||
def serialize(self, entity):
|
def serialize(self, entity):
|
||||||
return jsonutils.dumps(entity)
|
return jsonutils.dumps(entity)
|
||||||
|
|
||||||
@staticmethod
|
def request(self, *args, **kwargs):
|
||||||
def _decode_body(resp):
|
|
||||||
if resp.text:
|
|
||||||
try:
|
|
||||||
body_resp = jsonutils.loads(resp.text)
|
|
||||||
except (ValueError, TypeError):
|
|
||||||
body_resp = None
|
|
||||||
_logger.debug("Could not decode JSON from body: %s",
|
|
||||||
resp.text)
|
|
||||||
else:
|
|
||||||
_logger.debug("No body was returned.")
|
|
||||||
body_resp = None
|
|
||||||
|
|
||||||
return body_resp
|
|
||||||
|
|
||||||
def request(self, url, method, **kwargs):
|
|
||||||
"""Send an http request with the specified characteristics.
|
"""Send an http request with the specified characteristics.
|
||||||
|
|
||||||
Wrapper around requests.request to handle tasks such as
|
Wrapper around requests.request to handle tasks such as
|
||||||
setting headers, JSON encoding/decoding, and error handling.
|
setting headers, JSON encoding/decoding, and error handling.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
*DEPRECATED*: This function is no longer used. It was designed to
|
||||||
|
be used only by the managers and the managers now receive an
|
||||||
|
adapter so this function is no longer on the standard request path.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
|
||||||
kwargs['json'] = kwargs.pop('body')
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
kwargs.setdefault('authenticated', False)
|
kwargs.setdefault('authenticated', False)
|
||||||
resp = super(HTTPClient, self).request(url, method, **kwargs)
|
return self._adapter.request(*args, **kwargs)
|
||||||
return resp, self._decode_body(resp)
|
|
||||||
|
|
||||||
def _cs_request(self, url, method, management=True, **kwargs):
|
def _cs_request(self, url, method, management=True, **kwargs):
|
||||||
"""Makes an authenticated request to keystone endpoint by
|
"""Makes an authenticated request to keystone endpoint by
|
||||||
concatenating self.management_url and url and passing in method and
|
concatenating self.management_url and url and passing in method and
|
||||||
any associated kwargs.
|
any associated kwargs.
|
||||||
"""
|
"""
|
||||||
# NOTE(jamielennox): remember that if you use the legacy client mode
|
# NOTE(jamielennox): This is deprecated and is no longer a part of the
|
||||||
# (you create a client without a session) then this HTTPClient object
|
# standard client request path. It now goes via the adapter instead.
|
||||||
# is the auth plugin you are using. Values in the endpoint_filter may
|
if not management:
|
||||||
# be ignored and you should look at get_endpoint to figure out what.
|
endpoint_filter = kwargs.setdefault('endpoint_filter', {})
|
||||||
interface = 'admin' if management else 'public'
|
endpoint_filter.setdefault('interface', 'public')
|
||||||
endpoint_filter = kwargs.setdefault('endpoint_filter', {})
|
|
||||||
endpoint_filter.setdefault('service_type', 'identity')
|
|
||||||
endpoint_filter.setdefault('interface', interface)
|
|
||||||
|
|
||||||
if self.version:
|
|
||||||
endpoint_filter.setdefault('version', self.version)
|
|
||||||
|
|
||||||
if self.region_name:
|
|
||||||
endpoint_filter.setdefault('region_name', self.region_name)
|
|
||||||
|
|
||||||
kwargs.setdefault('authenticated', None)
|
kwargs.setdefault('authenticated', None)
|
||||||
try:
|
return self.request(url, method, **kwargs)
|
||||||
return self.request(url, method, **kwargs)
|
|
||||||
except exceptions.MissingAuthPlugin:
|
|
||||||
_logger.info(_LI('Cannot get authenticated endpoint without an '
|
|
||||||
'auth plugin'))
|
|
||||||
raise exceptions.AuthorizationFailure(
|
|
||||||
_('Current authorization does not have a known management '
|
|
||||||
'url'))
|
|
||||||
|
|
||||||
def get(self, url, **kwargs):
|
def get(self, url, **kwargs):
|
||||||
|
"""Perform an authenticated GET request.
|
||||||
|
|
||||||
|
This calls :py:meth:`.request()` with ``method`` set to ``GET`` and an
|
||||||
|
authentication token if one is available.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
*DEPRECATED*: This function is no longer used. It was designed to
|
||||||
|
be used by the managers and the managers now receive an adapter so
|
||||||
|
this function is no longer on the standard request path.
|
||||||
|
"""
|
||||||
return self._cs_request(url, 'GET', **kwargs)
|
return self._cs_request(url, 'GET', **kwargs)
|
||||||
|
|
||||||
def head(self, url, **kwargs):
|
def head(self, url, **kwargs):
|
||||||
|
"""Perform an authenticated HEAD request.
|
||||||
|
|
||||||
|
This calls :py:meth:`.request()` with ``method`` set to ``HEAD`` and an
|
||||||
|
authentication token if one is available.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
*DEPRECATED*: This function is no longer used. It was designed to
|
||||||
|
be used by the managers and the managers now receive an adapter so
|
||||||
|
this function is no longer on the standard request path.
|
||||||
|
"""
|
||||||
return self._cs_request(url, 'HEAD', **kwargs)
|
return self._cs_request(url, 'HEAD', **kwargs)
|
||||||
|
|
||||||
def post(self, url, **kwargs):
|
def post(self, url, **kwargs):
|
||||||
|
"""Perform an authenticate POST request.
|
||||||
|
|
||||||
|
This calls :py:meth:`.request()` with ``method`` set to ``POST`` and an
|
||||||
|
authentication token if one is available.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
*DEPRECATED*: This function is no longer used. It was designed to
|
||||||
|
be used by the managers and the managers now receive an adapter so
|
||||||
|
this function is no longer on the standard request path.
|
||||||
|
"""
|
||||||
return self._cs_request(url, 'POST', **kwargs)
|
return self._cs_request(url, 'POST', **kwargs)
|
||||||
|
|
||||||
def put(self, url, **kwargs):
|
def put(self, url, **kwargs):
|
||||||
|
"""Perform an authenticate PUT request.
|
||||||
|
|
||||||
|
This calls :py:meth:`.request()` with ``method`` set to ``PUT`` and an
|
||||||
|
authentication token if one is available.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
*DEPRECATED*: This function is no longer used. It was designed to
|
||||||
|
be used by the managers and the managers now receive an adapter so
|
||||||
|
this function is no longer on the standard request path.
|
||||||
|
"""
|
||||||
return self._cs_request(url, 'PUT', **kwargs)
|
return self._cs_request(url, 'PUT', **kwargs)
|
||||||
|
|
||||||
def patch(self, url, **kwargs):
|
def patch(self, url, **kwargs):
|
||||||
|
"""Perform an authenticate PATCH request.
|
||||||
|
|
||||||
|
This calls :py:meth:`.request()` with ``method`` set to ``PATCH`` and
|
||||||
|
an authentication token if one is available.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
*DEPRECATED*: This function is no longer used. It was designed to
|
||||||
|
be used by the managers and the managers now receive an adapter so
|
||||||
|
this function is no longer on the standard request path.
|
||||||
|
"""
|
||||||
return self._cs_request(url, 'PATCH', **kwargs)
|
return self._cs_request(url, 'PATCH', **kwargs)
|
||||||
|
|
||||||
def delete(self, url, **kwargs):
|
def delete(self, url, **kwargs):
|
||||||
|
"""Perform an authenticate DELETE request.
|
||||||
|
|
||||||
|
This calls :py:meth:`.request()` with ``method`` set to ``DELETE`` and
|
||||||
|
an authentication token if one is available.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
*DEPRECATED*: This function is no longer used. It was designed to
|
||||||
|
be used by the managers and the managers now receive an adapter so
|
||||||
|
this function is no longer on the standard request path.
|
||||||
|
"""
|
||||||
return self._cs_request(url, 'DELETE', **kwargs)
|
return self._cs_request(url, 'DELETE', **kwargs)
|
||||||
|
|
||||||
# DEPRECATIONS: The following methods are no longer directly supported
|
# DEPRECATIONS: The following methods are no longer directly supported
|
||||||
@@ -656,20 +732,40 @@ class HTTPClient(baseclient.Client, base.BaseAuthPlugin):
|
|||||||
'timeout': None,
|
'timeout': None,
|
||||||
'verify_cert': 'verify'}
|
'verify_cert': 'verify'}
|
||||||
|
|
||||||
|
deprecated_adapter_variables = {'region_name': None}
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
# FIXME(jamielennox): provide a proper deprecated warning
|
# FIXME(jamielennox): provide a proper deprecated warning
|
||||||
try:
|
try:
|
||||||
var_name = self.deprecated_session_variables[name]
|
var_name = self.deprecated_session_variables[name]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise AttributeError(_("Unknown Attribute: %s") % name)
|
pass
|
||||||
|
else:
|
||||||
|
return getattr(self.session, var_name or name)
|
||||||
|
|
||||||
return getattr(self.session, var_name or name)
|
try:
|
||||||
|
var_name = self.deprecated_adapter_variables[name]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
return getattr(self._adapter, var_name or name)
|
||||||
|
|
||||||
|
raise AttributeError(_("Unknown Attribute: %s") % name)
|
||||||
|
|
||||||
def __setattr__(self, name, val):
|
def __setattr__(self, name, val):
|
||||||
# FIXME(jamielennox): provide a proper deprecated warning
|
# FIXME(jamielennox): provide a proper deprecated warning
|
||||||
try:
|
try:
|
||||||
var_name = self.deprecated_session_variables[name]
|
var_name = self.deprecated_session_variables[name]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
super(HTTPClient, self).__setattr__(name, val)
|
pass
|
||||||
else:
|
else:
|
||||||
setattr(self.session, var_name or name)
|
return setattr(self.session, var_name or name)
|
||||||
|
|
||||||
|
try:
|
||||||
|
var_name = self.deprecated_adapter_variables[name]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
return setattr(self._adapter, var_name or name)
|
||||||
|
|
||||||
|
super(HTTPClient, self).__setattr__(name, val)
|
||||||
|
@@ -40,8 +40,8 @@ class BaseTest(utils.TestCase):
|
|||||||
auth_url='http://127.0.0.1:5000',
|
auth_url='http://127.0.0.1:5000',
|
||||||
endpoint='http://127.0.0.1:5000')
|
endpoint='http://127.0.0.1:5000')
|
||||||
|
|
||||||
self.client.get = self.mox.CreateMockAnything()
|
self.client._adapter.get = self.mox.CreateMockAnything()
|
||||||
self.client.get('/OS-KSADM/roles/1').AndRaise(AttributeError)
|
self.client._adapter.get('/OS-KSADM/roles/1').AndRaise(AttributeError)
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
f = roles.Role(self.client.roles, {'id': 1, 'name': 'Member'})
|
f = roles.Role(self.client.roles, {'id': 1, 'name': 'Member'})
|
||||||
|
@@ -130,17 +130,19 @@ class Client(httpclient.HTTPClient):
|
|||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
"""Initialize a new client for the Keystone v2.0 API."""
|
"""Initialize a new client for the Keystone v2.0 API."""
|
||||||
super(Client, self).__init__(**kwargs)
|
super(Client, self).__init__(**kwargs)
|
||||||
self.endpoints = endpoints.EndpointManager(self)
|
|
||||||
self.extensions = extensions.ExtensionManager(self)
|
|
||||||
self.roles = roles.RoleManager(self)
|
|
||||||
self.services = services.ServiceManager(self)
|
|
||||||
self.tokens = tokens.TokenManager(self)
|
|
||||||
self.users = users.UserManager(self, self.roles)
|
|
||||||
|
|
||||||
self.tenants = tenants.TenantManager(self, self.roles, self.users)
|
self.endpoints = endpoints.EndpointManager(self._adapter)
|
||||||
|
self.extensions = extensions.ExtensionManager(self._adapter)
|
||||||
|
self.roles = roles.RoleManager(self._adapter)
|
||||||
|
self.services = services.ServiceManager(self._adapter)
|
||||||
|
self.tokens = tokens.TokenManager(self._adapter)
|
||||||
|
self.users = users.UserManager(self._adapter, self.roles)
|
||||||
|
|
||||||
|
self.tenants = tenants.TenantManager(self._adapter,
|
||||||
|
self.roles, self.users)
|
||||||
|
|
||||||
# extensions
|
# extensions
|
||||||
self.ec2 = ec2.CredentialsManager(self)
|
self.ec2 = ec2.CredentialsManager(self._adapter)
|
||||||
|
|
||||||
# DEPRECATED: if session is passed then we go to the new behaviour of
|
# DEPRECATED: if session is passed then we go to the new behaviour of
|
||||||
# authenticating on the first required call.
|
# authenticating on the first required call.
|
||||||
|
@@ -78,7 +78,7 @@ class UserManager(base.ManagerWithFind):
|
|||||||
return self._update("/OS-KSCRUD/users/%s" % self.api.user_id, params,
|
return self._update("/OS-KSCRUD/users/%s" % self.api.user_id, params,
|
||||||
response_key="access",
|
response_key="access",
|
||||||
method="PATCH",
|
method="PATCH",
|
||||||
management=False,
|
endpoint_filter={'interface': 'public'},
|
||||||
log=False)
|
log=False)
|
||||||
|
|
||||||
def update_tenant(self, user, tenant):
|
def update_tenant(self, user, tenant):
|
||||||
|
@@ -169,23 +169,26 @@ EndpointPolicyManager`
|
|||||||
"""Initialize a new client for the Keystone v3 API."""
|
"""Initialize a new client for the Keystone v3 API."""
|
||||||
super(Client, self).__init__(**kwargs)
|
super(Client, self).__init__(**kwargs)
|
||||||
|
|
||||||
self.credentials = credentials.CredentialManager(self)
|
self.credentials = credentials.CredentialManager(self._adapter)
|
||||||
self.endpoint_filter = endpoint_filter.EndpointFilterManager(self)
|
self.endpoint_filter = endpoint_filter.EndpointFilterManager(
|
||||||
self.endpoint_policy = endpoint_policy.EndpointPolicyManager(self)
|
self._adapter)
|
||||||
self.endpoints = endpoints.EndpointManager(self)
|
self.endpoint_policy = endpoint_policy.EndpointPolicyManager(
|
||||||
self.domains = domains.DomainManager(self)
|
self._adapter)
|
||||||
self.federation = federation.FederationManager(self)
|
self.endpoints = endpoints.EndpointManager(self._adapter)
|
||||||
self.groups = groups.GroupManager(self)
|
self.domains = domains.DomainManager(self._adapter)
|
||||||
self.oauth1 = oauth1.create_oauth_manager(self)
|
self.federation = federation.FederationManager(self._adapter)
|
||||||
self.policies = policies.PolicyManager(self)
|
self.groups = groups.GroupManager(self._adapter)
|
||||||
self.projects = projects.ProjectManager(self)
|
self.oauth1 = oauth1.create_oauth_manager(self._adapter)
|
||||||
self.regions = regions.RegionManager(self)
|
self.policies = policies.PolicyManager(self._adapter)
|
||||||
self.role_assignments = role_assignments.RoleAssignmentManager(self)
|
self.projects = projects.ProjectManager(self._adapter)
|
||||||
self.roles = roles.RoleManager(self)
|
self.regions = regions.RegionManager(self._adapter)
|
||||||
self.services = services.ServiceManager(self)
|
self.role_assignments = (
|
||||||
self.tokens = tokens.TokenManager(self)
|
role_assignments.RoleAssignmentManager(self._adapter))
|
||||||
self.trusts = trusts.TrustManager(self)
|
self.roles = roles.RoleManager(self._adapter)
|
||||||
self.users = users.UserManager(self)
|
self.services = services.ServiceManager(self._adapter)
|
||||||
|
self.tokens = tokens.TokenManager(self._adapter)
|
||||||
|
self.trusts = trusts.TrustManager(self._adapter)
|
||||||
|
self.users = users.UserManager(self._adapter)
|
||||||
|
|
||||||
# DEPRECATED: if session is passed then we go to the new behaviour of
|
# DEPRECATED: if session is passed then we go to the new behaviour of
|
||||||
# authenticating on the first required call.
|
# authenticating on the first required call.
|
||||||
|
@@ -15,6 +15,8 @@
|
|||||||
from keystoneclient import base
|
from keystoneclient import base
|
||||||
from keystoneclient import exceptions
|
from keystoneclient import exceptions
|
||||||
from keystoneclient.i18n import _
|
from keystoneclient.i18n import _
|
||||||
|
from keystoneclient.v3 import endpoints
|
||||||
|
from keystoneclient.v3 import projects
|
||||||
|
|
||||||
|
|
||||||
class EndpointFilterManager(base.Manager):
|
class EndpointFilterManager(base.Manager):
|
||||||
@@ -72,8 +74,8 @@ class EndpointFilterManager(base.Manager):
|
|||||||
base_url = self._build_base_url(project=project)
|
base_url = self._build_base_url(project=project)
|
||||||
return super(EndpointFilterManager, self)._list(
|
return super(EndpointFilterManager, self)._list(
|
||||||
base_url,
|
base_url,
|
||||||
self.client.endpoints.collection_key,
|
endpoints.EndpointManager.collection_key,
|
||||||
obj_class=self.client.endpoints.resource_class)
|
obj_class=endpoints.EndpointManager.resource_class)
|
||||||
|
|
||||||
def list_projects_for_endpoint(self, endpoint):
|
def list_projects_for_endpoint(self, endpoint):
|
||||||
"""List all projects for a given endpoint."""
|
"""List all projects for a given endpoint."""
|
||||||
@@ -83,5 +85,5 @@ class EndpointFilterManager(base.Manager):
|
|||||||
base_url = self._build_base_url(endpoint=endpoint)
|
base_url = self._build_base_url(endpoint=endpoint)
|
||||||
return super(EndpointFilterManager, self)._list(
|
return super(EndpointFilterManager, self)._list(
|
||||||
base_url,
|
base_url,
|
||||||
self.client.projects.collection_key,
|
projects.ProjectManager.collection_key,
|
||||||
obj_class=self.client.projects.resource_class)
|
obj_class=projects.ProjectManager.resource_class)
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
from keystoneclient import base
|
from keystoneclient import base
|
||||||
from keystoneclient.i18n import _
|
from keystoneclient.i18n import _
|
||||||
|
from keystoneclient.v3 import endpoints
|
||||||
from keystoneclient.v3 import policies
|
from keystoneclient.v3 import policies
|
||||||
|
|
||||||
|
|
||||||
@@ -150,5 +151,5 @@ class EndpointPolicyManager(base.Manager):
|
|||||||
'ext_name': self.OS_EP_POLICY_EXT}
|
'ext_name': self.OS_EP_POLICY_EXT}
|
||||||
return self._list(
|
return self._list(
|
||||||
url,
|
url,
|
||||||
self.client.endpoints.collection_key,
|
endpoints.EndpointManager.collection_key,
|
||||||
obj_class=self.client.endpoints.resource_class)
|
obj_class=endpoints.EndpointManager.resource_class)
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from keystoneclient import auth
|
||||||
from keystoneclient import base
|
from keystoneclient import base
|
||||||
from keystoneclient.v3.contrib.oauth1 import utils
|
from keystoneclient.v3.contrib.oauth1 import utils
|
||||||
|
|
||||||
@@ -39,8 +40,9 @@ class AccessTokenManager(base.CrudManager):
|
|||||||
resource_owner_secret=request_secret,
|
resource_owner_secret=request_secret,
|
||||||
signature_method=oauth1.SIGNATURE_HMAC,
|
signature_method=oauth1.SIGNATURE_HMAC,
|
||||||
verifier=verifier)
|
verifier=verifier)
|
||||||
url = self.client.auth_url.rstrip("/") + endpoint
|
url = self.api.get_endpoint(interface=auth.AUTH_INTERFACE).rstrip('/')
|
||||||
url, headers, body = oauth_client.sign(url, http_method='POST')
|
url, headers, body = oauth_client.sign(url + endpoint,
|
||||||
|
http_method='POST')
|
||||||
resp, body = self.client.post(endpoint, headers=headers)
|
resp, body = self.client.post(endpoint, headers=headers)
|
||||||
token = utils.get_oauth_token_from_body(resp.content)
|
token = utils.get_oauth_token_from_body(resp.content)
|
||||||
return self.resource_class(self, token)
|
return self.resource_class(self, token)
|
||||||
|
@@ -15,6 +15,7 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
from six.moves.urllib import parse as urlparse
|
from six.moves.urllib import parse as urlparse
|
||||||
|
|
||||||
|
from keystoneclient import auth
|
||||||
from keystoneclient import base
|
from keystoneclient import base
|
||||||
from keystoneclient.v3.contrib.oauth1 import utils
|
from keystoneclient.v3.contrib.oauth1 import utils
|
||||||
|
|
||||||
@@ -62,8 +63,9 @@ class RequestTokenManager(base.CrudManager):
|
|||||||
client_secret=consumer_secret,
|
client_secret=consumer_secret,
|
||||||
signature_method=oauth1.SIGNATURE_HMAC,
|
signature_method=oauth1.SIGNATURE_HMAC,
|
||||||
callback_uri="oob")
|
callback_uri="oob")
|
||||||
url = self.client.auth_url.rstrip("/") + endpoint
|
url = self.api.get_endpoint(interface=auth.AUTH_INTERFACE).rstrip("/")
|
||||||
url, headers, body = oauth_client.sign(url, http_method='POST',
|
url, headers, body = oauth_client.sign(url + endpoint,
|
||||||
|
http_method='POST',
|
||||||
headers=headers)
|
headers=headers)
|
||||||
resp, body = self.client.post(endpoint, headers=headers)
|
resp, body = self.client.post(endpoint, headers=headers)
|
||||||
token = utils.get_oauth_token_from_body(resp.content)
|
token = utils.get_oauth_token_from_body(resp.content)
|
||||||
|
@@ -158,8 +158,8 @@ class UserManager(base.CrudManager):
|
|||||||
|
|
||||||
base_url = '/users/%s/password' % self.api.user_id
|
base_url = '/users/%s/password' % self.api.user_id
|
||||||
|
|
||||||
return self._update(base_url, params, method='POST', management=False,
|
return self._update(base_url, params, method='POST', log=False,
|
||||||
log=False)
|
endpoint_filter={'interface': 'public'})
|
||||||
|
|
||||||
def add_to_group(self, user, group):
|
def add_to_group(self, user, group):
|
||||||
self._require_user_and_group(user, group)
|
self._require_user_and_group(user, group)
|
||||||
|
Reference in New Issue
Block a user