184 lines
6.5 KiB
Python
184 lines
6.5 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 keystoneauth1 import access
|
|
from keystoneauth1.identity import access as access_plugin
|
|
from keystoneauth1 import loading
|
|
from keystoneauth1 import session as keystone_session
|
|
from keystoneclient.v3 import client as kc_v3
|
|
from oslo_config import cfg
|
|
from oslo_log import log as logging
|
|
|
|
from karbor import exception
|
|
from karbor import utils
|
|
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
CONF = cfg.CONF
|
|
|
|
# the config of trustee is like:
|
|
# [trustee]
|
|
# auth_type = password
|
|
# auth_url = http://192.168.1.2:35357
|
|
# username = karbor
|
|
# password = password
|
|
# user_domain_id = default
|
|
KEYSTONECLIENT_VERSION = (3, 0)
|
|
TRUSTEE_CONF_GROUP = 'trustee'
|
|
loading.register_auth_conf_options(CONF, TRUSTEE_CONF_GROUP)
|
|
CONF.import_group('keystone_authtoken',
|
|
'keystonemiddleware.auth_token')
|
|
|
|
|
|
class KarborKeystonePlugin(object):
|
|
"""Contruct a keystone client plugin with karbor user
|
|
|
|
to offer the following functions:
|
|
|
|
1. get the endpoint of service, such as nova, cinder
|
|
2. create trust to karbor
|
|
"""
|
|
|
|
def __init__(self):
|
|
self._client = None
|
|
self._auth_uri = None
|
|
self._karbor_user_id = None
|
|
auth_plugin = self._get_karbor_auth_plugin()
|
|
self._service_auth_plugin = auth_plugin
|
|
|
|
@property
|
|
def karbor_user_id(self):
|
|
if not self._karbor_user_id:
|
|
lcfg = CONF[TRUSTEE_CONF_GROUP]
|
|
self._karbor_user_id = self._get_service_user(
|
|
lcfg.username, lcfg.user_domain_id)
|
|
return self._karbor_user_id
|
|
|
|
@property
|
|
def client(self):
|
|
if not self._client:
|
|
self._client = self._get_keystone_client(self.service_auth_plugin)
|
|
return self._client
|
|
|
|
@property
|
|
def auth_uri(self):
|
|
if not self._auth_uri:
|
|
try:
|
|
self._auth_uri = utils.get_auth_uri()
|
|
except Exception:
|
|
msg = 'get keystone auth url failed'
|
|
raise exception.AuthorizationFailure(obj=msg)
|
|
return self._auth_uri
|
|
|
|
@property
|
|
def service_auth_plugin(self):
|
|
return self._service_auth_plugin
|
|
|
|
def get_service_endpoint(self, service_name, service_type,
|
|
region_id, interface='public'):
|
|
if self._auth_uri and self._auth_uri.endswith('/'):
|
|
base_url = self._auth_uri[:-1]
|
|
else:
|
|
base_url = self._auth_uri
|
|
try:
|
|
service = self.client.services.list(
|
|
name=service_name,
|
|
service_type=service_type,
|
|
base_url=base_url)
|
|
|
|
endpoint = self.client.endpoints.list(
|
|
service=service[0],
|
|
interface=interface,
|
|
region_id=region_id,
|
|
base_url=base_url)
|
|
|
|
return endpoint[0].url if endpoint else None
|
|
|
|
except Exception:
|
|
msg = ('get service(%s) endpoint failed' % service_name)
|
|
raise exception.AuthorizationFailure(obj=msg)
|
|
|
|
def create_user_auth_plugin(self, context):
|
|
if not context.auth_token_info:
|
|
msg = ("user=%s, project=%s" % (context.user_id,
|
|
context.project_id))
|
|
raise exception.AuthorizationFailure(obj=msg)
|
|
|
|
auth_ref = access.create(body=context.auth_token_info,
|
|
auth_token=context.auth_token)
|
|
return access_plugin.AccessInfoPlugin(
|
|
auth_url=self.auth_uri, auth_ref=auth_ref)
|
|
|
|
def create_trust_to_karbor(self, context):
|
|
l_kc_v3 = self._get_keystone_client(
|
|
self.create_user_auth_plugin(context))
|
|
keystone_trust_url = self.auth_uri + 'OS-TRUST'
|
|
try:
|
|
trust = l_kc_v3.trusts.create(trustor_user=context.user_id,
|
|
trustee_user=self.karbor_user_id,
|
|
project=context.project_id,
|
|
impersonation=True,
|
|
role_names=context.roles,
|
|
base_url=keystone_trust_url)
|
|
return trust.id
|
|
|
|
except Exception as e:
|
|
raise exception.AuthorizationFailure(obj=str(e))
|
|
|
|
def delete_trust_to_karbor(self, trust_id):
|
|
auth_plugin = self._get_karbor_auth_plugin(trust_id)
|
|
client = self._get_keystone_client(auth_plugin)
|
|
client.trusts.delete(trust_id)
|
|
|
|
def create_trust_session(self, trust_id):
|
|
auth_plugin = self._get_karbor_auth_plugin(trust_id)
|
|
cafile = cfg.CONF.keystone_authtoken.cafile
|
|
return keystone_session.Session(
|
|
auth=auth_plugin, verify=False if
|
|
CONF.keystone_authtoken.insecure else cafile)
|
|
|
|
def _get_service_user(self, user_name, user_domain_id):
|
|
try:
|
|
users = self.client.users.list(
|
|
name=user_name,
|
|
domain=user_domain_id)
|
|
|
|
return users[0].id if users else None
|
|
|
|
except Exception as e:
|
|
raise exception.AuthorizationFailure(obj=e)
|
|
|
|
def _get_karbor_auth_plugin(self, trust_id=None):
|
|
auth_plugin = loading.load_auth_from_conf_options(
|
|
CONF, TRUSTEE_CONF_GROUP, trust_id=trust_id)
|
|
|
|
if not auth_plugin:
|
|
LOG.warning('Please add the trustee credentials you need to the'
|
|
' %s section of your karbor.conf file.',
|
|
TRUSTEE_CONF_GROUP)
|
|
raise exception.AuthorizationFailure(obj=TRUSTEE_CONF_GROUP)
|
|
|
|
return auth_plugin
|
|
|
|
def _get_keystone_client(self, auth_plugin):
|
|
cafile = cfg.CONF.keystone_authtoken.cafile
|
|
try:
|
|
l_session = keystone_session.Session(
|
|
auth=auth_plugin, verify=False if
|
|
CONF.keystone_authtoken.insecure else cafile)
|
|
return kc_v3.Client(version=KEYSTONECLIENT_VERSION,
|
|
session=l_session)
|
|
except Exception:
|
|
msg = ('create keystone client failed.cafile:(%s)' % cafile)
|
|
raise exception.AuthorizationFailure(obj=msg)
|