From: Tony Mack Date: Tue, 14 Aug 2012 16:45:04 +0000 (-0400) Subject: group instances into tenants instead of running all instances in the admin tenant... X-Git-Tag: sfa-2.1-14~48 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=3a329faea5a72016c31c030bf27f6431f380fdee;p=sfa.git group instances into tenants instead of running all instances in the admin tenant. This fixes the quota problem --- diff --git a/sfa/openstack/client.py b/sfa/openstack/client.py index f0d717e6..215d3330 100644 --- a/sfa/openstack/client.py +++ b/sfa/openstack/client.py @@ -23,14 +23,26 @@ def parse_novarc(filename): class KeystoneClient: - def __init__(self, config=None): + def __init__(self, username=None, password=None, tenant=None, url=None, config=None): if not config: config = Config() opts = parse_novarc(config.SFA_NOVA_NOVARC) + if username: + opts['OS_USERNAME'] = username + if password: + opts['OS_PASSWORD'] = password + if tenant: + opts['OS_TENANT_NAME'] = tenant + if url: + opts['OS_AUTH_URL'] = url + self.opts = opts self.client = keystone_client.Client(username=opts.get('OS_USERNAME'), password=opts.get('OS_PASSWORD'), tenant_name=opts.get('OS_TENANT_NAME'), auth_url=opts.get('OS_AUTH_URL')) + + def connect(self, *args, **kwds): + self.__init__(*args, **kwds) def __getattr__(self, name): return getattr(self.client, name) @@ -50,10 +62,19 @@ class GlanceClient: return getattr(self.client, name) class NovaClient: - def __init__(self, config=None): + def __init__(self, username=None, password=None, tenant=None, url=None, config=None): if not config: config = Config() opts = parse_novarc(config.SFA_NOVA_NOVARC) + if username: + opts['OS_USERNAME'] = username + if password: + opts['OS_PASSWORD'] = password + if tenant: + opts['OS_TENANT_NAME'] = tenant + if url: + opts['OS_AUTH_URL'] = url + self.opts = opts self.client = nova_client.Client(username=opts.get('OS_USERNAME'), api_key=opts.get('OS_PASSWORD'), project_id=opts.get('OS_TENANT_NAME'), @@ -63,6 +84,9 @@ class NovaClient: service_type='compute', service_name='', ) + + def connect(self, *args, **kwds): + self.__init__(*args, **kwds) def __getattr__(self, name): return getattr(self.client, name) diff --git a/sfa/openstack/nova_driver.py b/sfa/openstack/nova_driver.py index 7fb53937..27795f73 100644 --- a/sfa/openstack/nova_driver.py +++ b/sfa/openstack/nova_driver.py @@ -43,7 +43,7 @@ class NovaDriver(Driver): def __init__ (self, config): Driver.__init__(self, config) - self.shell = Shell(config) + self.shell = Shell(config=config) self.cache=None if config.SFA_AGGREGATE_CACHING: if NovaDriver.cache is None: @@ -90,7 +90,9 @@ class NovaDriver(Driver): for researcher in researchers: name = Xrn(researcher).get_leaf() user = self.shell.auth_manager.users.find(name=name) + self.shell.auth_manager.roles.add_user_role(user, 'Member', tenant) self.shell.auth_manager.roles.add_user_role(user, 'user', tenant) + pis = sfa_record.get('pis', []) for pi in pis: @@ -432,6 +434,19 @@ class NovaDriver(Driver): aggregate = OSAggregate(self) rspec = RSpec(rspec_string) instance_name = hrn_to_os_slicename(slice_hrn) + + # make sure a tenant exists for this slice + tenant = aggregate.create_tenant(slice_hrn) + + # add the sfa admin user to this tenant and update our nova client connection + # to use these credentials for the rest of this session. This emsures that the instances + # we create will be assigned to the correct tenant. + sfa_admin_user = self.shell.auth_manager.users.find(name=self.shell.auth_manager.opts['OS_USERNAME']) + user_role = self.shell.auth_manager.roles.find(name='user') + admin_role = self.shell.auth_manager.roles.find(name='admin') + self.shell.auth_manager.roles.add_user_role(sfa_admin_user, admin_role, tenant) + self.shell.auth_manager.roles.add_user_role(sfa_admin_user, user_role, tenant) + self.shell.nova_manager.connect(tenant=tenant.name) # assume first user is the caller and use their context # for the ec2/euca api connection. Also, use the first users diff --git a/sfa/openstack/osaggregate.py b/sfa/openstack/osaggregate.py index 241ec0b5..519f8e82 100644 --- a/sfa/openstack/osaggregate.py +++ b/sfa/openstack/osaggregate.py @@ -99,9 +99,9 @@ class OSAggregate: node_xrn = instance.metadata.get('component_id') node_xrn if not node_xrn: - node_xrn = OSXrn('cloud', 'node') + node_xrn = OSXrn('cloud', type='node') else: - node_xrn = OSXrn(xrn=node_xrn, 'node') + node_xrn = OSXrn(xrn=node_xrn, type='node') rspec_node['component_id'] = node_xrn.urn rspec_node['component_name'] = node_xrn.name @@ -170,10 +170,21 @@ class OSAggregate: return rspec_nodes + def create_tenant(self, slice_hrn): + tenant_name = OSXrn(xrn=slice_hrn, type='slice').get_tenant_name() + tenants = self.driver.shell.auth_manager.tenants.findall(name=tenant_name) + if not tenants: + self.driver.shell.auth_manager.tenants.create(tenant_name, tenant_name) + tenant = self.driver.shell.auth_manager.tenants.find(name=tenant_name) + else: + tenant = tenants[0] + return tenant + + def create_instance_key(self, slice_hrn, user): slice_name = Xrn(slice_hrn).leaf user_name = Xrn(user['urn']).leaf - key_name = "%s:%s" % (slice_name, user_name) + key_name = "%s_%s" % (slice_name, user_name) pubkey = user['keys'][0] key_found = False existing_keys = self.driver.shell.nova_manager.keypairs.findall(name=key_name) diff --git a/sfa/openstack/shell.py b/sfa/openstack/shell.py index 7fab67f8..acb9cff5 100644 --- a/sfa/openstack/shell.py +++ b/sfa/openstack/shell.py @@ -31,9 +31,9 @@ class Shell: config = Config() if has_nova: # instantiate managers - self.auth_manager = KeystoneClient(config) - self.image_manager = GlanceClient(config) - self.nova_manager = NovaClient(config) + self.auth_manager = KeystoneClient(config=config) + self.image_manager = GlanceClient(config=config) + self.nova_manager = NovaClient(config=config) else: logger.debug('nova access - REST') raise SfaNotImplemented('nova access - Rest')