From 700366e4b6096cb502a638eb3ac9e0b95fefe44f Mon Sep 17 00:00:00 2001 From: Mike Fedosin Date: Sun, 9 Jul 2017 18:12:58 +0300 Subject: [PATCH] Use recommended function to setup auth middleware in devstack Currently Mistral has own configuration for keystone auth middleware, many parameters of which are deprecated [1]. It's not desired behavior and it is suggested to use recommended devstack configuration function to prevent possible errors if something is changed in keystone deployment in the future. This patch fixes this situation and implements official "configure_auth_token_middleware" function support. [1] https://github.com/openstack/keystonemiddleware/blob/712438ebf9ee30d553f6b515e38b1c91a9ae498e/keystonemiddleware/auth_token/_auth.py#L29-L35 Change-Id: I5f50ca6b773b61c35f93488e64a1b95d3ace9c2c Closes-bug: #1697662 --- devstack/plugin.sh | 15 +++-- devstack/settings | 1 + mistral/services/security.py | 3 +- mistral/utils/openstack/keystone.py | 90 +++++++++++++++++++---------- 4 files changed, 70 insertions(+), 39 deletions(-) diff --git a/devstack/plugin.sh b/devstack/plugin.sh index 36b71366e..334ea37bf 100755 --- a/devstack/plugin.sh +++ b/devstack/plugin.sh @@ -59,6 +59,11 @@ function mkdir_chown_stack { # configure_mistral - Set config files, create data dirs, etc function configure_mistral { + + # create and clean up auth cache dir + mkdir_chown_stack "$MISTRAL_AUTH_CACHE_DIR" + rm -f "$MISTRAL_AUTH_CACHE_DIR"/* + mkdir_chown_stack "$MISTRAL_CONF_DIR" # Generate Mistral configuration file and configure common parameters. @@ -75,14 +80,8 @@ function configure_mistral { #------------------------- # Setup keystone_authtoken section - iniset $MISTRAL_CONF_FILE keystone_authtoken auth_host $KEYSTONE_AUTH_HOST - iniset $MISTRAL_CONF_FILE keystone_authtoken auth_port $KEYSTONE_AUTH_PORT - iniset $MISTRAL_CONF_FILE keystone_authtoken auth_protocol $KEYSTONE_AUTH_PROTOCOL - iniset $MISTRAL_CONF_FILE keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME - iniset $MISTRAL_CONF_FILE keystone_authtoken admin_user $MISTRAL_ADMIN_USER - iniset $MISTRAL_CONF_FILE keystone_authtoken admin_password $SERVICE_PASSWORD + configure_auth_token_middleware $MISTRAL_CONF_FILE mistral $MISTRAL_AUTH_CACHE_DIR iniset $MISTRAL_CONF_FILE keystone_authtoken auth_uri $KEYSTONE_AUTH_URI_V3 - iniset $MISTRAL_CONF_FILE keystone_authtoken identity_uri $KEYSTONE_AUTH_URI # Setup RabbitMQ credentials iniset_rpc_backend mistral $MISTRAL_CONF_FILE @@ -249,8 +248,8 @@ if is_service_enabled mistral; then install_mistral_pythonclient elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then echo_summary "Configuring mistral" - configure_mistral create_mistral_accounts + configure_mistral elif [[ "$1" == "stack" && "$2" == "extra" ]]; then echo_summary "Initializing mistral" init_mistral diff --git a/devstack/settings b/devstack/settings index 9cddc9e33..b120d0f9f 100644 --- a/devstack/settings +++ b/devstack/settings @@ -29,6 +29,7 @@ MISTRAL_DASHBOARD_DIR=$DEST/mistral-dashboard MISTRAL_CONF_DIR=${MISTRAL_CONF_DIR:-/etc/mistral} MISTRAL_CONF_FILE=${MISTRAL_CONF_DIR}/mistral.conf MISTRAL_DEBUG=${MISTRAL_DEBUG:-True} +MISTRAL_AUTH_CACHE_DIR=${MISTRAL_AUTH_CACHE_DIR:-/var/cache/mistral} MISTRAL_SERVICE_HOST=${MISTRAL_SERVICE_HOST:-$SERVICE_HOST} MISTRAL_SERVICE_PORT=${MISTRAL_SERVICE_PORT:-8989} diff --git a/mistral/services/security.py b/mistral/services/security.py index f1fb4967c..b1ec0a410 100644 --- a/mistral/services/security.py +++ b/mistral/services/security.py @@ -42,8 +42,7 @@ def create_trust(): ctx = auth_ctx.ctx() - trustee_id = keystone.client_for_admin( - CONF.keystone_authtoken.admin_tenant_name).user_id + trustee_id = keystone.client_for_admin().session.get_user_id() return client.trusts.create( trustor_user=client.user_id, diff --git a/mistral/utils/openstack/keystone.py b/mistral/utils/openstack/keystone.py index cdb3a5cae..e8da18ef4 100644 --- a/mistral/utils/openstack/keystone.py +++ b/mistral/utils/openstack/keystone.py @@ -14,6 +14,7 @@ # limitations under the License. import keystoneauth1.identity.generic as auth_plugins +from keystoneauth1 import loading from keystoneauth1 import session as ks_session from keystoneauth1.token_endpoint import Token from keystoneclient import service_catalog as ks_service_catalog @@ -27,6 +28,7 @@ from mistral import context from mistral import exceptions CONF = cfg.CONF +CONF.register_opt(cfg.IntOpt('timeout'), group='keystone_authtoken') def client(): @@ -91,24 +93,48 @@ def get_session_and_auth(context, **kwargs): } -def _admin_client(trust_id=None, project_name=None): - auth_url = CONF.keystone_authtoken.auth_uri +def _admin_client(trust_id=None): + if CONF.keystone_authtoken.auth_type is None: + auth_url = CONF.keystone_authtoken.auth_uri - cl = ks_client.Client( - username=CONF.keystone_authtoken.admin_user, - password=CONF.keystone_authtoken.admin_password, - project_name=project_name, - auth_url=auth_url, - trust_id=trust_id - ) + cl = ks_client.Client( + username=CONF.keystone_authtoken.admin_user, + password=CONF.keystone_authtoken.admin_password, + project_name=CONF.keystone_authtoken.admin_tenant_name, + auth_url=auth_url, + trust_id=trust_id + ) - cl.management_url = auth_url + cl.management_url = auth_url - return cl + return cl + else: + kwargs = {} + + if trust_id: + # Remove project_name and project_id, since we need a trust scoped + # auth object + kwargs['project_name'] = None + kwargs['project_domain_name'] = None + kwargs['project_id'] = None + kwargs['trust_id'] = trust_id + + auth = loading.load_auth_from_conf_options( + CONF, + 'keystone_authtoken', + **kwargs + ) + sess = loading.load_session_from_conf_options( + CONF, + 'keystone_authtoken', + auth=auth + ) + + return ks_client.Client(session=sess) -def client_for_admin(project_name): - return _admin_client(project_name=project_name) +def client_for_admin(): + return _admin_client() def client_for_trusts(trust_id): @@ -230,28 +256,34 @@ def format_url(url_template, values): def is_token_trust_scoped(auth_token): - admin_project_name = CONF.keystone_authtoken.admin_tenant_name - keystone_client = _admin_client(project_name=admin_project_name) - - token_info = keystone_client.tokens.validate(auth_token) - - return 'OS-TRUST:trust' in token_info + return 'OS-TRUST:trust' in client_for_admin().tokens.validate(auth_token) def get_admin_session(): """Returns a keystone session from Mistral's service credentials.""" + if CONF.keystone_authtoken.auth_type is None: + auth = auth_plugins.Password( + CONF.keystone_authtoken.auth_uri, + username=CONF.keystone_authtoken.admin_user, + password=CONF.keystone_authtoken.admin_password, + project_name=CONF.keystone_authtoken.admin_tenant_name, + # NOTE(jaosorior): Once mistral supports keystone v3 properly, we + # can fetch the following values from the configuration. + user_domain_name='Default', + project_domain_name='Default') - auth = auth_plugins.Password( - CONF.keystone_authtoken.auth_uri, - username=CONF.keystone_authtoken.admin_user, - password=CONF.keystone_authtoken.admin_password, - project_name=CONF.keystone_authtoken.admin_tenant_name, - # NOTE(jaosorior): Once mistral supports keystone v3 properly, we can - # fetch the following values from the configuration. - user_domain_name='Default', - project_domain_name='Default') + return ks_session.Session(auth=auth) + else: + auth = loading.load_auth_from_conf_options( + CONF, + 'keystone_authtoken' + ) - return ks_session.Session(auth=auth) + return loading.load_session_from_conf_options( + CONF, + 'keystone_authtoken', + auth=auth + ) def will_expire_soon(expires_at):