def install_peer_certs(server_key_file, server_cert_file): """ Attempt to install missing trusted gids and db records for our federated interfaces """ # Attempt to get any missing peer gids # There should be a gid file in /etc/sfa/trusted_roots for every # peer registry found in in the registries.xml config file. If there # are any missing gids, request a new one from the peer registry. api = SfaApi(key_file = server_key_file, cert_file = server_cert_file) registries = Registries() aggregates = Aggregates() interfaces = dict(registries.items() + aggregates.items()) gids_current = api.auth.trusted_cert_list hrns_current = [gid.get_hrn() for gid in gids_current] hrns_expected = set([hrn for hrn in interfaces]) new_hrns = set(hrns_expected).difference(hrns_current) #gids = self.get_peer_gids(new_hrns) + gids_current peer_gids = [] if not new_hrns: return trusted_certs_dir = api.config.get_trustedroots_dir() for new_hrn in new_hrns: if not new_hrn: continue # the gid for this interface should already be installed if new_hrn == api.config.SFA_INTERFACE_HRN: continue try: # get gid from the registry url = interfaces[new_hrn].get_url() interface = interfaces[new_hrn].server_proxy(server_key_file, server_cert_file, timeout=30) # skip non sfa aggregates server_version = api.get_cached_server_version(interface) if 'sfa' not in server_version: logger.info("get_trusted_certs: skipping non sfa aggregate: %s" % new_hrn) continue trusted_gids = ReturnValue.get_value(interface.get_trusted_certs()) if trusted_gids: # the gid we want should be the first one in the list, # but lets make sure for trusted_gid in trusted_gids: # default message message = "interface: %s\t" % (api.interface) message += "unable to install trusted gid for %s" % \ (new_hrn) gid = GID(string=trusted_gid) peer_gids.append(gid) if gid.get_hrn() == new_hrn: gid_filename = os.path.join(trusted_certs_dir, '%s.gid' % new_hrn) gid.save_to_file(gid_filename, save_parents=True) message = "installed trusted cert for %s" % new_hrn # log the message api.logger.info(message) except: message = "interface: %s\tunable to install trusted gid for %s" % \ (api.interface, new_hrn) api.logger.log_exc(message) # doesnt matter witch one update_cert_records(peer_gids)
def Delete(self, api, xrn, creds, options): call_id = options.get('call_id') if Callids().already_handled(call_id): return "" def _Delete(server, xrn, creds, options): return server.Delete(xrn, creds, options) (hrn, type) = urn_to_hrn(xrn[0]) # get the callers hrn valid_cred = api.auth.checkCredentials(creds, 'deletesliver', hrn)[0] caller_hrn = Credential(cred=valid_cred).get_gid_caller().get_hrn() # attempt to use delegated credential first cred = api.getDelegatedCredential(creds) if not cred: cred = api.getCredential() multiclient = MultiClient() for aggregate in api.aggregates: # prevent infinite loop. Dont send request back to caller # unless the caller is the aggregate's SM if caller_hrn == aggregate and aggregate != api.hrn: continue interface = api.aggregates[aggregate] server = api.server_proxy(interface, cred) multiclient.run(_Delete, server, xrn, [cred], options) results = [] for result in multiclient.get_results(): results += ReturnValue.get_value(result) return results
def Provision(self, api, xrn, creds, options): call_id = options.get('call_id') if Callids().already_handled(call_id): return "" version_manager = VersionManager() def _Provision(aggregate, server, xrn, credential, options): tStart = time.time() try: # Need to call GetVersion at an aggregate to determine the supported # rspec type/format beofre calling CreateSliver at an Aggregate. server_version = api.get_cached_server_version(server) result = server.Provision(xrn, credential, options) return {"aggregate": aggregate, "result": result, "elapsed": time.time()-tStart, "status": "success"} except: logger.log_exc('Something wrong in _Allocate with URL %s'%server.url) return {"aggregate": aggregate, "elapsed": time.time()-tStart, "status": "exception", "exc_info": sys.exc_info()} # attempt to use delegated credential first cred = api.getDelegatedCredential(creds) if not cred: cred = api.getCredential() # get the callers hrn valid_cred = api.auth.checkCredentials(creds, 'createsliver', xrn)[0] caller_hrn = Credential(cred=valid_cred).get_gid_caller().get_hrn() multiclient = MultiClient() for aggregate in api.aggregates: # prevent infinite loop. Dont send request back to caller # unless the caller is the aggregate's SM if caller_hrn == aggregate and aggregate != api.hrn: continue interface = api.aggregates[aggregate] server = api.server_proxy(interface, cred) # Just send entire RSpec to each aggregate multiclient.run(_Provision, aggregate, server, xrn, [cred], options) results = multiclient.get_results() # Set the manifest of KOREN manifest_version = version_manager._get_version('KOREN', '1', 'manifest') # manifest_version = version_manager._get_version('GENI', '3', 'manifest') result_rspec = RSpec(version=manifest_version) geni_slivers = [] geni_urn = None for result in results: self.add_slicemgr_stat(result_rspec, "Provision", result["aggregate"], result["elapsed"], result["status"], result.get("exc_info",None)) if result["status"]=="success": try: res = result['result']['value'] geni_urn = res['geni_urn'] result_rspec.version.merge(ReturnValue.get_value(res['geni_rspec'])) geni_slivers.extend(res['geni_slivers']) except: api.logger.log_exc("SM.Provision: Failed to merge aggregate rspec") return { 'geni_urn': geni_urn, 'geni_rspec': result_rspec.toxml(), 'geni_slivers': geni_slivers }
def Provision(self, api, xrn, creds, options): call_id = options.get('call_id') if Callids().already_handled(call_id): return "" version_manager = VersionManager() def _Provision(aggregate, server, xrn, credential, options): tStart = time.time() try: # Need to call GetVersion at an aggregate to determine the supported # rspec type/format beofre calling CreateSliver at an Aggregate. server_version = api.get_cached_server_version(server) result = server.Provision(xrn, credential, options) return {"aggregate": aggregate, "result": result, "elapsed": time.time()-tStart, "status": "success"} except: logger.log_exc('Something wrong in _Allocate with URL %s'%server.url) return {"aggregate": aggregate, "elapsed": time.time()-tStart, "status": "exception", "exc_info": sys.exc_info()} # attempt to use delegated credential first cred = api.getDelegatedCredential(creds) if not cred: cred = api.getCredential() # get the callers hrn valid_cred = api.auth.checkCredentials(creds, 'createsliver', xrn)[0] caller_hrn = Credential(cred=valid_cred).get_gid_caller().get_hrn() multiclient = MultiClient() for aggregate in api.aggregates: # prevent infinite loop. Dont send request back to caller # unless the caller is the aggregate's SM if caller_hrn == aggregate and aggregate != api.hrn: continue interface = api.aggregates[aggregate] server = api.server_proxy(interface, cred) # Just send entire RSpec to each aggregate multiclient.run(_Provision, aggregate, server, xrn, [cred], options) results = multiclient.get_results() manifest_version = version_manager._get_version('GENI', '3', 'manifest') result_rspec = RSpec(version=manifest_version) geni_slivers = [] geni_urn = None for result in results: self.add_slicemgr_stat(result_rspec, "Provision", result["aggregate"], result["elapsed"], result["status"], result.get("exc_info",None)) if result["status"]=="success": try: res = result['result']['value'] geni_urn = res['geni_urn'] result_rspec.version.merge(ReturnValue.get_value(res['geni_rspec'])) geni_slivers.extend(res['geni_slivers']) except: api.logger.log_exc("SM.Provision: Failed to merge aggregate rspec") return { 'geni_urn': geni_urn, 'geni_rspec': result_rspec.toxml(), 'geni_slivers': geni_slivers }
def get_cached_server_version(self, server): cache_key = server.url + "-version" server_version = None if self.cache: server_version = self.cache.get(cache_key) if not server_version: result = server.GetVersion() server_version = ReturnValue.get_value(result) # cache version for 24 hours self.cache.add(cache_key, server_version, ttl= 60*60*24) return server_version
def get_cached_server_version(self, server): cache_key = server.url + "-version" server_version = None if self.cache: server_version = self.cache.get(cache_key) if not server_version: result = server.GetVersion() server_version = ReturnValue.get_value(result) # cache version for 24 hours self.cache.add(cache_key, server_version, ttl=60 * 60 * 24) return server_version
def Describe(self, api, creds, xrns, options): def _Describe(server, xrn, creds, options): return server.Describe(xrn, creds, options) call_id = options.get('call_id') if Callids().already_handled(call_id): return {} # attempt to use delegated credential first cred = api.getDelegatedCredential(creds) if not cred: cred = api.getCredential() multiclient = MultiClient() for aggregate in api.aggregates: interface = api.aggregates[aggregate] server = api.server_proxy(interface, cred) multiclient.run (_Describe, server, xrns, [cred], options) results = [ReturnValue.get_value(result) for result in multiclient.get_results()] # get rid of any void result - e.g. when call_id was hit, where by convention we return {} results = [ result for result in results if result and result.get('geni_urn')] # do not try to combine if there's no result if not results : return {} # otherwise let's merge stuff version_manager = VersionManager() manifest_version = version_manager._get_version('GENI', '3', 'manifest') result_rspec = RSpec(version=manifest_version) geni_slivers = [] geni_urn = None for result in results: try: geni_urn = result['geni_urn'] result_rspec.version.merge(ReturnValue.get_value(result['geni_rspec'])) geni_slivers.extend(result['geni_slivers']) except: api.logger.log_exc("SM.Provision: Failed to merge aggregate rspec") return { 'geni_urn': geni_urn, 'geni_rspec': result_rspec.toxml(), 'geni_slivers': geni_slivers }
def get_version(self): ### if we already know the answer: if self.probed: return self._version ### otherwise let's look in the cache file logger.debug("searching in version cache %s" % self.url()) cached_version = VersionCache().get(self.url()) if cached_version is not None: logger.info("Retrieved version info from cache %s" % self.url()) return cached_version ### otherwise let's do the hard work # dummy to meet Sfi's expectations for its 'options' field class DummyOptions: pass options = DummyOptions() options.verbose = self.verbose options.timeout = 10 try: client = Sfi(options) client.read_config() client.bootstrap() key_file = client.private_key cert_file = client.my_gid logger.debug("using key %s & cert %s" % (key_file, cert_file)) url = self.url() logger.info('issuing GetVersion at %s' % url) # setting timeout here seems to get the call to fail - even though the response time is fast #server=SfaServerProxy(url, key_file, cert_file, verbose=self.verbose, timeout=options.timeout) server = SfaServerProxy(url, key_file, cert_file, verbose=self.verbose) self._version = ReturnValue.get_value(server.GetVersion()) except: logger.log_exc("failed to get version") self._version = {} # so that next run from this process will find out self.probed = True # store in version cache so next processes will remember for an hour cache = VersionCache() cache.set(self.url(), self._version) cache.save() logger.debug("Saved version for url=%s in version cache" % self.url()) # that's our result return self._version
def ListSlices(self, api, creds, options): call_id = options.get('call_id') if Callids().already_handled(call_id): return [] def _ListSlices(server, creds, options): return server.ListSlices(creds, options) # look in cache first # xxx is this really frequent enough that it is worth being cached ? if self.cache: slices = self.cache.get('slices') if slices: api.logger.debug("SliceManager.ListSlices returns from cache") return slices # get the callers hrn valid_cred = api.auth.checkCredentials(creds, 'listslices', None)[0] caller_hrn = Credential(string=valid_cred).get_gid_caller().get_hrn() # attempt to use delegated credential first cred= api.getDelegatedCredential(creds) if not cred: cred = api.getCredential() threads = ThreadManager() # fetch from aggregates for aggregate in api.aggregates: # prevent infinite loop. Dont send request back to caller # unless the caller is the aggregate's SM if caller_hrn == aggregate and aggregate != api.hrn: continue interface = api.aggregates[aggregate] server = api.server_proxy(interface, cred) threads.run(_ListSlices, server, [cred], options) # combime results results = [ReturnValue.get_value(result) for result in threads.get_results()] slices = [] for result in results: slices.extend(result) # cache the result if self.cache: api.logger.debug("SliceManager.ListSlices caches value") self.cache.add('slices', slices) return slices
def SliverStatus(self, api, slice_xrn, creds, options): def _SliverStatus(server, xrn, creds, options): return server.SliverStatus(xrn, creds, options) call_id = options.get('call_id') if Callids().already_handled(call_id): return {} # attempt to use delegated credential first cred = api.getDelegatedCredential(creds) if not cred: cred = api.getCredential() threads = ThreadManager() for aggregate in api.aggregates: interface = api.aggregates[aggregate] server = api.server_proxy(interface, cred) threads.run (_SliverStatus, server, slice_xrn, [cred], options) results = [ReturnValue.get_value(result) for result in threads.get_results()] # get rid of any void result - e.g. when call_id was hit, where by convention we return {} results = [ result for result in results if result and result['geni_resources']] # do not try to combine if there's no result if not results : return {} # otherwise let's merge stuff overall = {} # mmh, it is expected that all results carry the same urn overall['geni_urn'] = results[0]['geni_urn'] overall['pl_login'] = None for result in results: if result.get('pl_login'): overall['pl_login'] = result['pl_login'] break elif isinstance(result.get('value'), dict) and result['value'].get('pl_login'): overall['pl_login'] = result['value']['pl_login'] break # append all geni_resources overall['geni_resources'] = \ reduce (lambda x,y: x+y, [ result['geni_resources'] for result in results] , []) overall['status'] = 'unknown' if overall['geni_resources']: overall['status'] = 'ready' return overall
def get_version(self): ### if we already know the answer: if self.probed: return self._version ### otherwise let's look in the cache file logger.debug("searching in version cache %s"%self.url()) cached_version = VersionCache().get(self.url()) if cached_version is not None: logger.info("Retrieved version info from cache %s"%self.url()) return cached_version ### otherwise let's do the hard work # dummy to meet Sfi's expectations for its 'options' field class DummyOptions: pass options=DummyOptions() options.verbose=self.verbose options.timeout=10 try: client=Sfi(options) client.read_config() client.bootstrap() key_file = client.private_key cert_file = client.my_gid logger.debug("using key %s & cert %s"%(key_file,cert_file)) url=self.url() logger.info('issuing GetVersion at %s'%url) # setting timeout here seems to get the call to fail - even though the response time is fast #server=SfaServerProxy(url, key_file, cert_file, verbose=self.verbose, timeout=options.timeout) server=SfaServerProxy(url, key_file, cert_file, verbose=self.verbose) self._version=ReturnValue.get_value(server.GetVersion()) except: logger.log_exc("failed to get version") self._version={} # so that next run from this process will find out self.probed=True # store in version cache so next processes will remember for an hour cache=VersionCache() cache.set(self.url(),self._version) cache.save() logger.debug("Saved version for url=%s in version cache"%self.url()) # that's our result return self._version
def Status(self, api, slice_xrn, creds, options): def _Status(server, xrn, creds, options): return server.Status(xrn, creds, options) call_id = options.get('call_id') if Callids().already_handled(call_id): return {} # attempt to use delegated credential first cred = api.getDelegatedCredential(creds) if not cred: cred = api.getCredential() multiclient = MultiClient() for aggregate in api.aggregates: interface = api.aggregates[aggregate] server = api.server_proxy(interface, cred) multiclient.run (_Status, server, slice_xrn, [cred], options) results = [ReturnValue.get_value(result) for result in multiclient.get_results()] # get rid of any void result - e.g. when call_id was hit, where by convention we return {} results = [ result for result in results if result and result['geni_slivers']] # do not try to combine if there's no result if not results : return {} # otherwise let's merge stuff geni_slivers = [] geni_urn = None for result in results: try: geni_urn = result['geni_urn'] geni_slivers.extend(result['geni_slivers']) except: api.logger.log_exc("SM.Provision: Failed to merge aggregate rspec") return { 'geni_urn': geni_urn, 'geni_slivers': geni_slivers }
def get_cached_server_version(self, server, options): # check local cache first cache = None version = None cache_file = os.path.join(options.sfi_dir,'sfi_cache.dat') cache_key = server.url + "-version" try: cache = Cache(cache_file) except IOError: cache = Cache() self.logger.info("Local cache not found at: %s" % cache_file) if cache: version = cache.get(cache_key) if not version: result = server.GetVersion() version= ReturnValue.get_value(result) # cache version for 20 minutes cache.add(cache_key, version, ttl= 60*20) self.logger.info("Updating cache file %s" % cache_file) cache.save_to_file(cache_file) return version
def install_peer_certs(server_key_file, server_cert_file): """ Attempt to install missing trusted gids and db records for our federated interfaces """ # Attempt to get any missing peer gids # There should be a gid file in /etc/sfa/trusted_roots for every # peer registry found in in the registries.xml config file. If there # are any missing gids, request a new one from the peer registry. api = SfaApi(key_file=server_key_file, cert_file=server_cert_file) registries = Registries() aggregates = Aggregates() interfaces = dict(registries.items() + aggregates.items()) gids_current = api.auth.trusted_cert_list hrns_current = [gid.get_hrn() for gid in gids_current] hrns_expected = set([hrn for hrn in interfaces]) new_hrns = set(hrns_expected).difference(hrns_current) #gids = self.get_peer_gids(new_hrns) + gids_current peer_gids = [] if not new_hrns: return trusted_certs_dir = api.config.get_trustedroots_dir() for new_hrn in new_hrns: if not new_hrn: continue # the gid for this interface should already be installed if new_hrn == api.config.SFA_INTERFACE_HRN: continue try: # get gid from the registry url = interfaces[new_hrn].get_url() interface = interfaces[new_hrn].server_proxy(server_key_file, server_cert_file, timeout=30) # skip non sfa aggregates server_version = api.get_cached_server_version(interface) if 'sfa' not in server_version: logger.info( "get_trusted_certs: skipping non sfa aggregate: %s" % new_hrn) continue trusted_gids = ReturnValue.get_value(interface.get_trusted_certs()) if trusted_gids: # the gid we want should be the first one in the list, # but lets make sure for trusted_gid in trusted_gids: # default message message = "interface: %s\t" % (api.interface) message += "unable to install trusted gid for %s" % \ (new_hrn) gid = GID(string=trusted_gid) peer_gids.append(gid) if gid.get_hrn() == new_hrn: gid_filename = os.path.join(trusted_certs_dir, '%s.gid' % new_hrn) gid.save_to_file(gid_filename, save_parents=True) message = "installed trusted cert for %s" % new_hrn # log the message api.logger.info(message) except: message = "interface: %s\tunable to install trusted gid for %s" % \ (api.interface, new_hrn) api.logger.log_exc(message) # doesnt matter witch one update_cert_records(peer_gids)
def add_resource(self, parent_id, name, typename, config, owner = None): if not parent_id: raise ValueError("Need a parent") #Creating a new SFI client object # sfi = Sfi() # sfi.read_config() # sfi.bootstrap() # credentials = [ sfi.my_credential_string ] # bootstrap = sfi.bootstrap.server_proxy(sfi.sm_url) #Create new options version_dict = {'type':'SFA', 'version':'1','schema':None,'namespace':None,'extensions':[]} options = {} options[ 'geni_rspec_version' ] = version_dict #Getting the configuration paramter of the parent resource, in this case an RSpec parent = self.__manager.get_resource(parent_id) pconfig = parent.get_configuration() rspec = pconfig['xmlRspec'] logger.debug('RSpec of the parent %s'%rspec) #Saving the hostname of the parent in order to retrieve the slice later hostname = self.fetch_tag(rspec,'hostname') logger.debug('Saved the hostname %s'%hostname) #Getting the vctname and creating the slice_hrn slice_hrn = 'raven.fts.%s' %config['vctname'] slice_urn = hrn_to_urn(slice_hrn, 'slice') logger.info('Creating or updating a slice with the name %s'%slice_hrn) #Preparing the server_proxy object and getting the server version result = self.__bootstrap.GetVersion() server_version= ReturnValue.get_value(result) logger.debug('Received server version %s'%server_version) #Creating the slice record dict or string #recorddict = dict({'hrn': slice_hrn, #'url': 'http://planet-lab.org', #'type': 'slice', #'researcher': ['teagle.teagle.teagle'], #'description': 'Teagle slice'}) slice_str = '<record description="Teagle Slice4" hrn="%s" type="slice" url="http://planet-lab.org"><researcher>teagle.teagle.teagle</researcher></record>' %slice_hrn slicerecord = SfaRecord(string = slice_str).as_dict() logger.debug('Prepared a slice record to add to the registry %s'%slice_str) #Retrieving the credential of the authority auth_cred = self.__sfi.bootstrap.authority_credential_string (self.__sfi.authority) #auth_cred = sfi.bootstrap.authority_credential_string (sfi.authority) logger.debug('Authority %s credentials %s'%(self.__sfi.authority, auth_cred,)) #logger.debug('Authority %s credentials %s'%(sfi.authority, auth_cred,)) #Trying to create the slice try: records = self.registry().Register(slicerecord, auth_cred) #records = self.registry(sfi).Register(slicerecord, auth_cred) except ServerException: logger.debug("Slice already existing") pass #Saving the slice credential creds = [self.__sfi.slice_credential_string(slice_hrn)] #creds = [sfi.slice_credential_string(slice_hrn)] logger.debug('The slice credential: %s'%creds) # users # need to pass along user keys to the aggregate. # users = [ # { urn: urn:publicid:IDN+emulab.net+user+alice # keys: [<ssh key A>, <ssh key B>] # }] users = [] slice_records = self.registry().Resolve(slice_urn, [self.__sfi.my_credential_string]) #slice_records = self.registry(sfi).Resolve(slice_urn, [sfi.my_credential_string]) if slice_records and 'researcher' in slice_records[0] and slice_records[0]['researcher']!=[]: slice_record = slice_records[0] user_hrns = slice_record['researcher'] user_urns = [hrn_to_urn(hrn, 'user') for hrn in user_hrns] user_records = self.registry().Resolve(user_urns, [self.__sfi.my_credential_string]) #user_records = self.registry(sfi).Resolve(user_urns, [sfi.my_credential_string]) if 'sfa' not in server_version: users = pg_users_arg(user_records) rspec = RSpec(rspec) rspec.filter({'component_manager_id': server_version['urn']}) rspec = RSpecConverter.to_pg_rspec(rspec.toxml(), content_type='request') else: users = sfa_users_arg(user_records, slice_record) logger.debug('Creating the sliver using the RSpec %s'%rspec) time.sleep(5) #Creating the sliver logger.debug("###################slice_urn: %s"%(slice_urn,)) logger.debug("###################creds: %s"%(creds,)) logger.debug("###################rspec: %s"%(rspec,)) logger.debug("###################users: %s"%(users,)) logger.debug("###################options: %s"%(options,)) result = self.__bootstrap.CreateSliver(slice_urn, creds, rspec, users, options) #result = bootstrap.CreateSliver(slice_urn, creds, rspec, users,options) value = ReturnValue.get_value(result) logger.debug("###################return value: %s"%(value, )) options['geni_slice_urn'] = hrn_to_urn(slice_hrn, 'slice') options['call_id'] = unique_call_id() slice_credentials = self.__sfi.slice_credential_string(slice_hrn) #slice_credentials = sfi.slice_credential_string(slice_hrn) list_resources = self.__bootstrap.ListResources(slice_credentials, options) #list_resources = bootstrap.ListResources(slice_credentials,options) #self.__sfi.bootstrap.server_proxy(self.__sfi.sm_url) logger.debug( "ListResources of slice %s returned : %s"%(slice_hrn,list_resources['value'])) slice_rspec = RSpec(list_resources['value']) nodes = slice_rspec.version.get_nodes() for node in nodes: component_name = '' component_name = node['component_name'] tags = self.convert_tags(node['tags']) node_hostname = tags['hostname'] if hostname in node_hostname: #store the information of the specific sliver in the config ###XXX change the username with the real sliver name sliver_name = self.fetch_username(slice_rspec) ip = self.fetch_ip(slice_rspec) name = '%s.%s'%(hostname,sliver_name,) conf = {'public_ip':ip,'username':sliver_name,'password':None} #self.__config['/SFAVNode-%s' %name] = conf self.__config[name] = conf logger.info('Adding the resource instance %s '%name) time.sleep(10) if not self.poll_machine(ip, sliver_name): raise Exception('Connection with the sliver not possible') if name in self.__instances: raise DuplicateNameError(parent_id, typename, name) self.__instances.add(name) return name
threads.run(_ListResources, aggregate, server, [cred], options) results = threads.get_results() rspec_version = version_manager.get_version(options.get('geni_rspec_version')) if xrn: result_version = version_manager._get_version(rspec_version.type, rspec_version.version, 'manifest') else: result_version = version_manager._get_version(rspec_version.type, rspec_version.version, 'ad') rspec = RSpec(version=result_version) for result in results: self.add_slicemgr_stat(rspec, "ListResources", result["aggregate"], result["elapsed"], result["status"], result.get("exc_info",None)) if result["status"]=="success": try: rspec.version.merge(ReturnValue.get_value(result["rspec"])) except: api.logger.log_exc("SM.ListResources: Failed to merge aggregate rspec") # cache the result if self.cache and not xrn: api.logger.debug("SliceManager.ListResources caches advertisement") self.cache.add(version_string, rspec.toxml()) return rspec.toxml() def CreateSliver(self, api, xrn, creds, rspec_str, users, options): call_id = options.get('call_id') if Callids().already_handled(call_id): return ""
def Allocate(self, api, xrn, creds, rspec_str, expiration, options): call_id = options.get('call_id') if Callids().already_handled(call_id): return "" version_manager = VersionManager() def _Allocate(aggregate, server, xrn, credential, rspec, options): tStart = time.time() try: # Need to call GetVersion at an aggregate to determine the supported # rspec type/format beofre calling CreateSliver at an Aggregate. #server_version = api.get_cached_server_version(server) #if 'sfa' not in server_version and 'geni_api' in server_version: # sfa aggregtes support both sfa and pg rspecs, no need to convert # if aggregate supports sfa rspecs. otherwise convert to pg rspec #rspec = RSpec(RSpecConverter.to_pg_rspec(rspec, 'request')) #filter = {'component_manager_id': server_version['urn']} #rspec.filter(filter) #rspec = rspec.toxml() result = server.Allocate(xrn, credential, rspec, options) return {"aggregate": aggregate, "result": result, "elapsed": time.time()-tStart, "status": "success"} except: logger.log_exc('Something wrong in _Allocate with URL %s'%server.url) return {"aggregate": aggregate, "elapsed": time.time()-tStart, "status": "exception", "exc_info": sys.exc_info()} # Validate the RSpec against PlanetLab's schema --disabled for now # The schema used here needs to aggregate the PL and VINI schemas # schema = "/var/www/html/schemas/pl.rng" rspec = RSpec(rspec_str) # schema = None # if schema: # rspec.validate(schema) # if there is a <statistics> section, the aggregates don't care about it, # so delete it. self.drop_slicemgr_stats(rspec) # attempt to use delegated credential first cred = api.getDelegatedCredential(creds) if not cred: cred = api.getCredential() # get the callers hrn hrn, type = urn_to_hrn(xrn) valid_cred = api.auth.checkCredentials(creds, 'createsliver', hrn)[0] caller_hrn = Credential(cred=valid_cred).get_gid_caller().get_hrn() multiclient = MultiClient() for aggregate in api.aggregates: # prevent infinite loop. Dont send request back to caller # unless the caller is the aggregate's SM if caller_hrn == aggregate and aggregate != api.hrn: continue interface = api.aggregates[aggregate] server = api.server_proxy(interface, cred) # Just send entire RSpec to each aggregate multiclient.run(_Allocate, aggregate, server, xrn, [cred], rspec.toxml(), options) results = multiclient.get_results() manifest_version = version_manager._get_version(rspec.version.type, rspec.version.version, 'manifest') result_rspec = RSpec(version=manifest_version) geni_urn = None geni_slivers = [] for result in results: self.add_slicemgr_stat(result_rspec, "Allocate", result["aggregate"], result["elapsed"], result["status"], result.get("exc_info",None)) if result["status"]=="success": try: res = result['result']['value'] geni_urn = res['geni_urn'] result_rspec.version.merge(ReturnValue.get_value(res['geni_rspec'])) geni_slivers.extend(res['geni_slivers']) except: api.logger.log_exc("SM.Allocate: Failed to merge aggregate rspec") return { 'geni_urn': geni_urn, 'geni_rspec': result_rspec.toxml(), 'geni_slivers': geni_slivers }
results = multiclient.get_results() rspec_version = version_manager.get_version(options.get('geni_rspec_version')) if xrn: result_version = version_manager._get_version(rspec_version.type, rspec_version.version, 'manifest') else: result_version = version_manager._get_version(rspec_version.type, rspec_version.version, 'ad') rspec = RSpec(version=result_version) for result in results: self.add_slicemgr_stat(rspec, "ListResources", result["aggregate"], result["elapsed"], result["status"], result.get("exc_info",None)) if result["status"]=="success": res = result['result']['value'] try: rspec.version.merge(ReturnValue.get_value(res)) except: api.logger.log_exc("SM.ListResources: Failed to merge aggregate rspec") # cache the result if self.cache and not xrn: api.logger.debug("SliceManager.ListResources caches advertisement") self.cache.add(version_string, rspec.toxml()) return rspec.toxml() def Allocate(self, api, xrn, creds, rspec_str, expiration, options): call_id = options.get('call_id') if Callids().already_handled(call_id): return ""