python-keystoneclient/keystoneclient/v3/client.py

350 lines
14 KiB
Python

# Copyright 2011 Nebula, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import logging
import warnings
from oslo_serialization import jsonutils
from keystoneclient.auth.identity import v3 as v3_auth
from keystoneclient import exceptions
from keystoneclient import httpclient
from keystoneclient.i18n import _
from keystoneclient.v3 import application_credentials
from keystoneclient.v3 import auth
from keystoneclient.v3.contrib import endpoint_filter
from keystoneclient.v3.contrib import endpoint_policy
from keystoneclient.v3.contrib import federation
from keystoneclient.v3.contrib import oauth1
from keystoneclient.v3.contrib import simple_cert
from keystoneclient.v3.contrib import trusts
from keystoneclient.v3 import credentials
from keystoneclient.v3 import domain_configs
from keystoneclient.v3 import domains
from keystoneclient.v3 import ec2
from keystoneclient.v3 import endpoint_groups
from keystoneclient.v3 import endpoints
from keystoneclient.v3 import groups
from keystoneclient.v3 import limits
from keystoneclient.v3 import policies
from keystoneclient.v3 import projects
from keystoneclient.v3 import regions
from keystoneclient.v3 import registered_limits
from keystoneclient.v3 import role_assignments
from keystoneclient.v3 import roles
from keystoneclient.v3 import services
from keystoneclient.v3 import tokens
from keystoneclient.v3 import users
_logger = logging.getLogger(__name__)
class Client(httpclient.HTTPClient):
r"""Client for the OpenStack Identity API v3.
:param session: Session for requests. (optional)
:type session: keystoneauth1.session.Session
:param string user_id: User ID for authentication. (optional)
:param string username: Username for authentication. (optional)
:param string user_domain_id: User's domain ID for authentication.
(optional)
:param string user_domain_name: User's domain name for authentication.
(optional)
:param string password: Password for authentication. (optional)
:param string token: Token for authentication. (optional)
:param string domain_id: Domain ID for domain scoping. (optional)
:param string domain_name: Domain name for domain scoping. (optional)
:param string project_id: Project ID for project scoping. (optional)
:param string project_name: Project name for project scoping. (optional)
:param string project_domain_id: Project's domain ID for project
scoping. (optional)
:param string project_domain_name: Project's domain name for project
scoping. (optional)
:param string tenant_name: Tenant name. (optional)
The tenant_name keyword argument is deprecated
as of the 1.7.0 release in favor of project_name
and may be removed in the 2.0.0 release.
:param string tenant_id: Tenant id. (optional)
The tenant_id keyword argument is deprecated as of
the 1.7.0 release in favor of project_id and may
be removed in the 2.0.0 release.
:param string auth_url: Identity service endpoint for authorization.
:param string region_name: Name of a region to select when choosing an
endpoint from the service catalog.
:param string endpoint: A user-supplied endpoint URL for the identity
service. Lazy-authentication is possible for API
service calls if endpoint is set at
instantiation. (optional)
:param integer timeout: Allows customization of the timeout for client
http requests. (optional)
.. warning::
Constructing an instance of this class without a session is
deprecated as of the 1.7.0 release and will be removed in the
2.0.0 release.
Example::
>>> from keystoneauth1.identity import v3
>>> from keystoneauth1 import session
>>> from keystoneclient.v3 import client
>>> auth = v3.Password(user_domain_name=DOMAIN_NAME,
... username=USER,
... password=PASS,
... project_domain_name=PROJECT_DOMAIN_NAME,
... project_name=PROJECT_NAME,
... auth_url=KEYSTONE_URL)
>>> sess = session.Session(auth=auth)
>>> keystone = client.Client(session=sess)
>>> keystone.projects.list()
...
>>> user = keystone.users.get(USER_ID)
>>> user.delete()
Instances of this class have the following managers:
.. py:attribute:: credentials
:py:class:`keystoneclient.v3.credentials.CredentialManager`
.. py:attribute:: domain_configs
:py:class:`keystoneclient.v3.domain_configs.DomainConfigManager`
.. py:attribute:: ec2
:py:class:`keystoneclient.v3.ec2.EC2Manager`
.. py:attribute:: endpoint_filter
:py:class:`keystoneclient.v3.contrib.endpoint_filter.\
EndpointFilterManager`
.. py:attribute:: endpoint_groups
:py:class:`keystoneclient.v3.endpoint_groups.\
EndpointGroupManager`
.. py:attribute:: endpoint_policy
:py:class:`keystoneclient.v3.contrib.endpoint_policy.\
EndpointPolicyManager`
.. py:attribute:: endpoints
:py:class:`keystoneclient.v3.endpoints.EndpointManager`
.. py:attribute:: domains
:py:class:`keystoneclient.v3.domains.DomainManager`
.. py:attribute:: federation
:py:class:`keystoneclient.v3.contrib.federation.core.FederationManager`
.. py:attribute:: groups
:py:class:`keystoneclient.v3.groups.GroupManager`
.. py:attribute:: limits
:py:class:`keystoneclient.v3.limits.LimitManager`
.. py:attribute:: oauth1
:py:class:`keystoneclient.v3.contrib.oauth1.core.OAuthManager`
.. py:attribute:: policies
:py:class:`keystoneclient.v3.policies.PolicyManager`
.. py:attribute:: regions
:py:class:`keystoneclient.v3.regions.RegionManager`
.. py:attribute:: registered_limits
:py:class:`keystoneclient.v3.registered_limits.RegisteredLimitManager`
.. py:attribute:: role_assignments
:py:class:`keystoneclient.v3.role_assignments.RoleAssignmentManager`
.. py:attribute:: roles
:py:class:`keystoneclient.v3.roles.RoleManager`
.. py:attribute:: simple_cert
:py:class:`keystoneclient.v3.contrib.simple_cert.SimpleCertManager`
.. py:attribute:: services
:py:class:`keystoneclient.v3.services.ServiceManager`
.. py:attribute:: tokens
:py:class:`keystoneclient.v3.tokens.TokenManager`
.. py:attribute:: trusts
:py:class:`keystoneclient.v3.contrib.trusts.TrustManager`
.. py:attribute:: users
:py:class:`keystoneclient.v3.users.UserManager`
"""
version = 'v3'
def __init__(self, **kwargs):
"""Initialize a new client for the Keystone v3 API."""
super(Client, self).__init__(**kwargs)
if not kwargs.get('session'):
warnings.warn(
'Constructing an instance of the '
'keystoneclient.v3.client.Client class without a session is '
'deprecated as of the 1.7.0 release and may be removed in '
'the 2.0.0 release.', DeprecationWarning)
self.application_credentials = (
application_credentials.ApplicationCredentialManager(self._adapter)
)
self.auth = auth.AuthManager(self._adapter)
self.credentials = credentials.CredentialManager(self._adapter)
self.ec2 = ec2.EC2Manager(self._adapter)
self.endpoint_filter = endpoint_filter.EndpointFilterManager(
self._adapter)
self.endpoint_groups = endpoint_groups.EndpointGroupManager(
self._adapter)
self.endpoint_policy = endpoint_policy.EndpointPolicyManager(
self._adapter)
self.endpoints = endpoints.EndpointManager(self._adapter)
self.domain_configs = domain_configs.DomainConfigManager(self._adapter)
self.domains = domains.DomainManager(self._adapter)
self.federation = federation.FederationManager(self._adapter)
self.groups = groups.GroupManager(self._adapter)
self.limits = limits.LimitManager(self._adapter)
self.oauth1 = oauth1.create_oauth_manager(self._adapter)
self.policies = policies.PolicyManager(self._adapter)
self.projects = projects.ProjectManager(self._adapter)
self.registered_limits = registered_limits.RegisteredLimitManager(
self._adapter)
self.regions = regions.RegionManager(self._adapter)
self.role_assignments = (
role_assignments.RoleAssignmentManager(self._adapter))
self.roles = roles.RoleManager(self._adapter)
self.inference_rules = roles.InferenceRuleManager(self._adapter)
self.services = services.ServiceManager(self._adapter)
self.simple_cert = simple_cert.SimpleCertManager(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
# authenticating on the first required call.
if 'session' not in kwargs and self.management_url is None:
self.authenticate()
def serialize(self, entity):
return jsonutils.dumps(entity, sort_keys=True)
def process_token(self, **kwargs):
"""Extract and process information from the new auth_ref.
And set the relevant authentication information.
"""
super(Client, self).process_token(**kwargs)
if self.auth_ref.domain_scoped:
if not self.auth_ref.domain_id:
raise exceptions.AuthorizationFailure(
_("Token didn't provide domain_id"))
self._process_management_url(kwargs.get('region_name'))
self.domain_name = self.auth_ref.domain_name
self.domain_id = self.auth_ref.domain_id
if self._management_url:
self._management_url = self._management_url.replace('/v2.0', '/v3')
def get_raw_token_from_identity_service(self, auth_url, user_id=None,
username=None,
user_domain_id=None,
user_domain_name=None,
password=None,
domain_id=None, domain_name=None,
project_id=None, project_name=None,
project_domain_id=None,
project_domain_name=None,
token=None,
trust_id=None,
**kwargs):
"""Authenticate against the v3 Identity API.
If password and token methods are both provided then both methods will
be used in the request.
:returns: access.AccessInfo if authentication was successful.
:rtype: :class:`keystoneclient.access.AccessInfoV3`
:raises keystoneclient.exceptions.AuthorizationFailure: if unable to
authenticate or validate the existing authorization token.
:raises keystoneclient.exceptions.Unauthorized: if authentication fails
due to invalid token.
"""
try:
if auth_url is None:
raise ValueError(_("Cannot authenticate without an auth_url"))
auth_methods = []
if token:
auth_methods.append(v3_auth.TokenMethod(token=token))
if password:
m = v3_auth.PasswordMethod(user_id=user_id,
username=username,
user_domain_id=user_domain_id,
user_domain_name=user_domain_name,
password=password)
auth_methods.append(m)
if not auth_methods:
msg = _('A user and password or token is required.')
raise exceptions.AuthorizationFailure(msg)
plugin = v3_auth.Auth(auth_url, auth_methods,
trust_id=trust_id,
domain_id=domain_id,
domain_name=domain_name,
project_id=project_id,
project_name=project_name,
project_domain_id=project_domain_id,
project_domain_name=project_domain_name)
return plugin.get_auth_ref(self.session)
except (exceptions.AuthorizationFailure, exceptions.Unauthorized):
_logger.debug('Authorization failed.')
raise
except exceptions.EndpointNotFound:
msg = _('There was no suitable authentication url for this'
' request')
raise exceptions.AuthorizationFailure(msg)
except Exception as e:
raise exceptions.AuthorizationFailure(
_('Authorization failed: %s') % e)