senlin/senlin/drivers/os/keystone_v3.py

158 lines
5.3 KiB
Python

# 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.
from oslo_config import cfg
from oslo_log import log
from senlin.drivers import base
from senlin.drivers import sdk
LOG = log.getLogger(__name__)
CONF = cfg.CONF
class KeystoneClient(base.DriverBase):
"""Keystone V3 driver."""
def __init__(self, params):
super(KeystoneClient, self).__init__(params)
self.conn = sdk.create_connection(params)
self.session = self.conn.session
@sdk.translate_exception
def trust_get_by_trustor(self, trustor, trustee=None, project=None):
"""Get trust by trustor.
Note we cannot provide two or more filters to keystone due to
constraints in keystone implementation. We do additional filtering
after the results are returned.
:param trustor: ID of the trustor;
:param trustee: ID of the trustee;
:param project: ID of the project to which the trust is scoped.
:returns: The trust object or None if no matching trust is found.
"""
filters = {'trustor_user_id': trustor}
trusts = [t for t in self.conn.identity.trusts(**filters)]
for trust in trusts:
if (trustee and trust.trustee_user_id != trustee):
continue
if (project and trust.project_id != project):
continue
return trust
return None
@sdk.translate_exception
def trust_create(self, trustor, trustee, project, roles=None,
impersonation=True):
"""Create trust between two users.
:param trustor: ID of the user who is the trustor.
:param trustee: ID of the user who is the trustee.
:param project: Scope of the trust which is a project ID.
:param roles: List of roles the trustee will inherit from the trustor.
:param impersonation: Whether the trustee is allowed to impersonate
the trustor.
"""
# inherit the role of the trustor, unless CONF.trust_roles is set
if CONF.trust_roles:
role_list = [{'name': role} for role in CONF.trust_roles]
elif roles:
role_list = [{'name': role} for role in roles]
else:
role_list = []
params = {
'trustor_user_id': trustor,
'trustee_user_id': trustee,
'project_id': project,
'impersonation': impersonation,
'allow_redelegation': True,
'roles': role_list
}
result = self.conn.identity.create_trust(**params)
return result
@classmethod
@sdk.translate_exception
def get_token(cls, **creds):
"""Get token using given credential"""
access_info = sdk.authenticate(**creds)
return access_info['token']
@classmethod
@sdk.translate_exception
def get_user_id(cls, **creds):
"""Get ID of the user with given credential"""
access_info = sdk.authenticate(**creds)
return access_info['user_id']
@classmethod
def get_service_credentials(cls, **kwargs):
"""Senlin service credential to use with Keystone.
:param kwargs: An additional keyword argument list that can be used
for customizing the default settings.
"""
creds = {
'auth_url': CONF.authentication.auth_url,
'username': CONF.authentication.service_username,
'password': CONF.authentication.service_password,
'project_name': CONF.authentication.service_project_name,
'user_domain_name': cfg.CONF.authentication.service_user_domain,
'project_domain_name':
cfg.CONF.authentication.service_project_domain,
'verify': cfg.CONF.authentication.verify_ssl,
'interface': cfg.CONF.authentication.interface,
}
creds.update(**kwargs)
return creds
@sdk.translate_exception
def validate_regions(self, regions):
"""Check whether the given regions are valid.
:param regions: A list of regions for validation.
:returns: A list of regions that are found available on keystone.
"""
region_list = self.conn.identity.regions()
known = [r['id'] for r in region_list]
validated = []
for r in regions:
if r in known:
validated.append(r)
else:
LOG.warning('Region %s is not found.', r)
return validated
@sdk.translate_exception
def get_senlin_endpoint(self):
"""Get Senlin service endpoint."""
region = cfg.CONF.default_region_name
interface = cfg.CONF.authentication.interface
base = self.conn.session.get_endpoint(service_type='clustering',
interface=interface,
region_name=region)
return base