Adding trust delegation and removal for proxy users

Changes
* adding a generic keystone client creation function
* adding a function to create proxy user clients
* renaming admin client functions for clarity
* adding token delegation/removal during proxy user creation/deletion
* adding a configuration option for proxy user trust roles

Change-Id: I362a27c1b1d0c5b81d6fbbb91fc0689e339f0076
Partial-implements: blueprint edp-swift-trust-authentication
This commit is contained in:
Michael McCune 2014-08-23 14:10:32 -04:00
parent a539bcfdc9
commit c332e4f96d
4 changed files with 56 additions and 13 deletions

View File

@ -480,6 +480,10 @@
# Swift object access. (string value)
#proxy_user_domain_name=<None>
# A list of the role names that the proxy user should assume
# through trust for Swift object access. (list value)
#proxy_user_role_names=Member
#
# Options defined in sahara.utils.remote

View File

@ -113,7 +113,8 @@ def delete_trust_from_cluster(cluster):
'''
if cluster.trust_id:
keystone_client = keystone.client_for_trusts(cluster.trust_id)
keystone_client = keystone.client_for_admin_from_trust(
cluster.trust_id)
delete_trust(keystone_client, cluster.trust_id)
ctx = context.current()
conductor.cluster_update(ctx,
@ -136,7 +137,7 @@ def use_os_admin_auth_token(cluster):
ctx = context.current()
ctx.username = CONF.keystone_authtoken.admin_user
ctx.tenant_id = cluster.tenant_id
client = keystone.client_for_trusts(cluster.trust_id)
client = keystone.client_for_admin_from_trust(cluster.trust_id)
ctx.token = client.auth_token
ctx.service_catalog = json.dumps(
client.service_catalog.catalog['catalog'])

View File

@ -28,12 +28,14 @@ opts = [
default=True,
help='Enables Sahara to use Keystone API v3. '
'If that flag is disabled, '
'per-job clusters will not be terminated automatically.')
'per-job clusters will not be terminated '
'automatically.')
]
CONF.register_opts(opts)
def client():
'''Return the current context client.'''
ctx = context.current()
auth_url = base.retrieve_auth_url()
@ -52,27 +54,47 @@ def client():
return keystone
def _admin_client(project_name=None, trust_id=None):
def _client(username, password, project_name=None, trust_id=None,
domain_name=None):
if not CONF.use_identity_api_v3:
raise Exception('Trusts aren\'t implemented in keystone api'
' less than v3')
auth_url = base.retrieve_auth_url()
username = CONF.keystone_authtoken.admin_user
password = CONF.keystone_authtoken.admin_password
keystone = keystone_client_v3.Client(username=username,
password=password,
project_name=project_name,
user_domain_name=domain_name,
auth_url=auth_url,
trust_id=trust_id)
keystone.management_url = auth_url
return keystone
def _admin_client(project_name=None, trust_id=None):
username = CONF.keystone_authtoken.admin_user
password = CONF.keystone_authtoken.admin_password
keystone = _client(username=username,
password=password,
project_name=project_name,
trust_id=trust_id)
return keystone
def client_for_admin():
project_name = CONF.keystone_authtoken.admin_tenant_name
return _admin_client(project_name=project_name)
'''Return the Sahara admin user client.'''
return _admin_client(
project_name=CONF.keystone_authtoken.admin_tenant_name)
def client_for_trusts(trust_id):
def client_for_admin_from_trust(trust_id):
'''Return the Sahara admin user client scoped to a trust.'''
return _admin_client(trust_id=trust_id)
def client_for_proxy_user(username, password, trust_id=None):
'''Return a client for the proxy user specified.'''
return _client(username=username,
password=password,
domain_name=CONF.proxy_user_domain_name,
trust_id=trust_id)

View File

@ -23,6 +23,7 @@ from sahara import context
from sahara import exceptions as ex
from sahara.i18n import _
from sahara.openstack.common import log as logging
from sahara.service import trusts as t
from sahara.swift import utils as su
from sahara.utils.openstack import keystone as k
@ -41,7 +42,11 @@ opts = [
cfg.StrOpt('proxy_user_domain_name',
default=None,
help='The domain Sahara will use to create new proxy users '
'for Swift object access.')
'for Swift object access.'),
cfg.ListOpt('proxy_user_role_names',
default=['Member'],
help='A list of the role names that the proxy user should '
'assume through trust for Swift object access.')
]
CONF.register_opts(opts)
@ -54,10 +59,16 @@ def create_proxy_user_for_job_execution(job_execution):
'''
username = 'job_{0}'.format(job_execution.id)
password = proxy_user_create(username)
current_user = k.client()
proxy_user = k.client_for_proxy_user(username, password)
trust_id = t.create_trust(trustor=current_user,
trustee=proxy_user,
role_names=CONF.proxy_user_role_names)
update = {'job_configs': job_execution.job_configs.to_dict()}
update['job_configs']['proxy_configs'] = {
'proxy_username': username,
'proxy_password': password
'proxy_password': password,
'proxy_trust_id': trust_id
}
conductor.job_execution_update(context.ctx(), job_execution, update)
@ -72,8 +83,13 @@ def delete_proxy_user_for_job_execution(job_execution):
proxy_configs = job_execution.job_configs.get('proxy_configs')
if proxy_configs is not None:
proxy_username = proxy_configs.get('proxy_username')
if proxy_username is not None:
proxy_user_delete(proxy_username)
proxy_password = proxy_configs.get('proxy_password')
proxy_trust_id = proxy_configs.get('proxy_trust_id')
proxy_user = k.client_for_proxy_user(proxy_username,
proxy_password,
proxy_trust_id)
t.delete_trust(proxy_user, proxy_trust_id)
proxy_user_delete(proxy_username)
update = {'job_configs': job_execution.job_configs.to_dict()}
del update['job_configs']['proxy_configs']
return update