From 9c14bb6d6050fada49bb419f74b64c45268515d2 Mon Sep 17 00:00:00 2001 From: tengqm Date: Fri, 8 May 2015 03:53:50 -0400 Subject: [PATCH] Fix admin requirement in trust middleware Due to default policy.json settings in Keystone, a non-admin user is not allowed to call 'list_users' or 'get_user' APIs. However, Senlin only knows the user name but it needs a user ID to create the trust between service requester and the 'senlin' user. The only workaround today is to have Senlin query its own user ID using its user name. After this is done, the trust middleware will use the service requester's credential to raise the 'trust create' request to Keystone. This necessitates two changes to the current code, one is to relax Keystone's policy setting to allow a user with 'service' role to do user list and user get (proposed here: https://review.openstack.org/181298); the other one is to have Senlin trust middleware to raise user ID checking request using 'senlin' credential. This patch contains the second part. Since devstack doesn't provide a function to modify default policy settings, we will wait to see if the patch to Keystone will be accepted. If Keystone refuse to accept that change, we need to hack the devstack plugin and 'setup-service' tool to modify the policy.json file. Anyway, we need 'senlin' user to have a 'service' role in the requester's domain (default to 'demo'). Change-Id: I87146a54f79e32a9175755f42da1e4406842c0b7 --- devstack/lib/senlin | 4 ++-- senlin/api/middleware/trust.py | 39 +++++++++++++++++++++++----------- tools/setup-service | 8 ++++++- 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/devstack/lib/senlin b/devstack/lib/senlin index 71065adff..e125411df 100644 --- a/devstack/lib/senlin +++ b/devstack/lib/senlin @@ -171,8 +171,8 @@ function create_senlin_accounts { "$SERVICE_PROTOCOL://$SENLIN_API_HOST:$SENLIN_API_PORT/v1/\$(tenant_id)s" fi - # senlin_stack_user role is for users created by Senlin - # get_or_create_role "senlin_cluster_user" + # get or adds 'service' role to 'senlin' on 'demo' project + get_or_add_user_project_role "service" "senlin" "demo" } # Restore xtrace diff --git a/senlin/api/middleware/trust.py b/senlin/api/middleware/trust.py index 8e6d4bdd4..5b905c068 100644 --- a/senlin/api/middleware/trust.py +++ b/senlin/api/middleware/trust.py @@ -29,6 +29,31 @@ class TrustMiddleware(wsgi.Middleware): The extracted information is filled into the request context. Senlin engine will use this information for access control. ''' + def _get_service_user_id(self, ctx): + # Convert user name to user ID first + importutils.import_module('keystonemiddleware.auth_token') + admin_user = cfg.CONF.keystone_authtoken.admin_user + admin_passwd = cfg.CONF.keystone_authtoken.admin_password + + params = { + 'auth_url': ctx.auth_url, + 'user_name': admin_user, + 'password': admin_passwd, + # This is a hack, we need to know the domain name somehow + 'user_domain_name': 'Default', + } + + kc = keystone_v3.KeystoneClient(params) + + try: + admin_id = kc.user_get_by_name(admin_user) + except exception.UserNotFound: + # This is unacceptable, treat it as a server error + msg = _("Failed Senlin user checking.") + raise webob.exc.HTTPInternalServerError(msg) + + return admin_id + def _get_trust(self, ctx): '''List trusts with current user as the trustor.''' @@ -44,26 +69,16 @@ class TrustMiddleware(wsgi.Middleware): cred_exists = True pass + admin_id = self._get_service_user_id(ctx) + params = { 'auth_url': ctx.auth_url, 'auth_token': ctx.auth_token, 'project': ctx.project, 'user': ctx.user, } - kc = keystone_v3.KeystoneClient(params) - # Convert user name to user ID first - importutils.import_module('keystonemiddleware.auth_token') - admin_user = cfg.CONF.keystone_authtoken.admin_user - - try: - admin_id = kc.user_get_by_name(admin_user) - except exception.UserNotFound: - # This is unacceptable, treat it as a server error - msg = _("Failed Senlin user checking.") - raise webob.exc.HTTPInternalServerError(msg) - try: trusts = kc.trust_get_by_trustor(ctx.user, admin_id, ctx.project) except exception.TrustNotFound: diff --git a/tools/setup-service b/tools/setup-service index a6ee99b78..b0d23ea62 100755 --- a/tools/setup-service +++ b/tools/setup-service @@ -36,6 +36,12 @@ openstack user create \ senlin openstack role add \ - service \ + admin \ --user senlin \ --project service + +# make sure 'senlin' has 'service' role in 'demo' project +openstack role add \ + service \ + --user senlin \ + --project demo