def shutdown(self, xrn, options={}): hrn, _ = urn_to_hrn(xrn) top_auth_hrn = top_auth(hrn) site_hrn = '.'.join(hrn.split('.')[:-1]) slice_part = hrn.split('.')[-1] if top_auth_hrn == self.hrn: login_base = slice_hrn.split('.')[-2][:12] else: login_base = hash_loginbase(site_hrn) slicename = '_'.join([login_base, slice_part]) slices = self.shell.GetSlices({ 'peer_id': None, 'name': slicename }, ['slice_id']) if not slices: raise RecordNotFound(slice_hrn) slice_id = slices[0]['slice_id'] slice_tags = self.shell.GetSliceTags({ 'slice_id': slice_id, 'tagname': 'enabled' }) if not slice_tags: self.shell.AddSliceTag(slice_id, 'enabled', '0') elif slice_tags[0]['value'] != "0": tag_id = slice_tags[0]['slice_tag_id'] self.shell.UpdateSliceTag(tag_id, '0') return 1
def verify_slice(self, slice_hrn, slice_record, sfa_peer, expiration, options=None): if options is None: options={} top_auth_hrn = top_auth(slice_hrn) site_hrn = '.'.join(slice_hrn.split('.')[:-1]) slice_part = slice_hrn.split('.')[-1] if top_auth_hrn == self.driver.hrn: login_base = slice_hrn.split('.')[-2][:12] else: login_base = hash_loginbase(site_hrn) slice_name = '_'.join([login_base, slice_part]) expires = int(datetime_to_epoch(utcparse(expiration))) # Filter slices by HRN slices = self.driver.shell.GetSlices({'peer_id': None, 'hrn':slice_hrn}, ['slice_id','name','hrn','expires']) if slices: slice = slices[0] slice_id = slice['slice_id'] #Update expiration if necessary if slice.get('expires', None) != expires: self.driver.shell.UpdateSlice( slice_id, {'expires' : expires}) else: if slice_record: url = slice_record.get('url', slice_hrn) description = slice_record.get('description', slice_hrn) else: url = slice_hrn description = slice_hrn slice = {'name': slice_name, 'url': url, 'description': description, 'hrn': slice_hrn, 'sfa_created': 'True', #'expires': expires, } # add the slice slice_id = self.driver.shell.AddSlice(slice) # plcapi tends to mess with the incoming hrn so let's make sure self.driver.shell.SetSliceHrn (slice_id, slice_hrn) # cannot be set with AddSlice # set the expiration self.driver.shell.UpdateSlice(slice_id, {'expires': expires}) return self.driver.shell.GetSlices(slice_id)[0]
def verify_site(self, slice_xrn, slice_record=None, sfa_peer=None, options=None): if slice_record is None: slice_record={} if options is None: options={} (slice_hrn, type) = urn_to_hrn(slice_xrn) top_auth_hrn = top_auth(slice_hrn) site_hrn = '.'.join(slice_hrn.split('.')[:-1]) if top_auth_hrn == self.driver.hrn: login_base = slice_hrn.split('.')[-2][:12] else: login_base = hash_loginbase(site_hrn) # filter sites by hrn sites = self.driver.shell.GetSites({'peer_id': None, 'hrn':site_hrn}, ['site_id','name','abbreviated_name','login_base','hrn']) # alredy exists if sites: site = sites[0] else: # create new site record site = {'name': 'sfa:%s' % site_hrn, 'abbreviated_name': site_hrn, 'login_base': login_base, 'max_slices': 100, 'max_slivers': 1000, 'enabled': True, 'peer_site_id': None, 'hrn':site_hrn, 'sfa_created': 'True', } site_id = self.driver.shell.AddSite(site) # plcapi tends to mess with the incoming hrn so let's make sure self.driver.shell.SetSiteHrn (site_id, site_hrn) site['site_id'] = site_id # exempt federated sites from monitor policies self.driver.shell.AddSiteTag(site_id, 'exempt_site_until', "20200101") return site
def shutdown (self, xrn, options={}): hrn, _ = urn_to_hrn(xrn) top_auth_hrn = top_auth(hrn) site_hrn = '.'.join(hrn.split('.')[:-1]) slice_part = hrn.split('.')[-1] if top_auth_hrn == self.hrn: login_base = slice_hrn.split('.')[-2][:12] else: login_base = hash_loginbase(site_hrn) slicename = '_'.join([login_base, slice_part]) slices = self.shell.GetSlices({'peer_id': None, 'name': slicename}, ['slice_id']) if not slices: raise RecordNotFound(slice_hrn) slice_id = slices[0]['slice_id'] slice_tags = self.shell.GetSliceTags({'slice_id': slice_id, 'tagname': 'enabled'}) if not slice_tags: self.shell.AddSliceTag(slice_id, 'enabled', '0') elif slice_tags[0]['value'] != "0": tag_id = slice_tags[0]['slice_tag_id'] self.shell.UpdateSliceTag(tag_id, '0') return 1
def check_sliver_credentials(self, creds, urns): # build list of cred object hrns slice_cred_names = [] for cred in creds: slice_cred_hrn = Credential(cred=cred).get_gid_object().get_hrn() top_auth_hrn = top_auth(slice_cred_hrn) site_hrn = '.'.join(slice_cred_hrn.split('.')[:-1]) slice_part = slice_cred_hrn.split('.')[-1] if top_auth_hrn == self.hrn: login_base = slice_cred_hrn.split('.')[-2][:12] else: login_base = hash_loginbase(site_hrn) slicename = '_'.join([login_base, slice_part]) slice_cred_names.append(slicename) # look up slice name of slivers listed in urns arg slice_ids = [] for urn in urns: sliver_id_parts = Xrn(xrn=urn).get_sliver_id_parts() try: slice_ids.append(int(sliver_id_parts[0])) except ValueError: pass if not slice_ids: raise Forbidden("sliver urn not provided") slices = self.shell.GetSlices(slice_ids) sliver_names = [slice['name'] for slice in slices] # make sure we have a credential for every specified sliver ierd for sliver_name in sliver_names: if sliver_name not in slice_cred_names: msg = "Valid credential not found for target: %s" % sliver_name raise Forbidden(msg)
def verify_persons(self, slice_hrn, slice_record, users, sfa_peer, options=None): if options is None: options={} # first we annotate the incoming users arg with a 'hrn' key for user in users: user['hrn'], _ = urn_to_hrn(user['urn']) # this is for retrieving users from a hrn users_by_hrn = { user['hrn'] : user for user in users } for user in users: logger.debug("incoming user %s"%user) # compute the hrn's for the authority and site top_auth_hrn = top_auth(slice_hrn) site_hrn = '.'.join(slice_hrn.split('.')[:-1]) slice_part = slice_hrn.split('.')[-1] # deduce login_base and slice_name if top_auth_hrn == self.driver.hrn: login_base = slice_hrn.split('.')[-2][:12] else: login_base = hash_loginbase(site_hrn) slice_name = '_'.join([login_base, slice_part]) # locate the site object # due to a limitation in PLCAPI, we have to specify 'hrn' as part of the return fields site = self.driver.shell.GetSites ({'peer_id':None, 'hrn':site_hrn}, ['site_id','hrn'])[0] site_id = site['site_id'] # locate the slice object slice = self.driver.shell.GetSlices ({'peer_id':None, 'hrn':slice_hrn}, ['slice_id','hrn','person_ids'])[0] slice_id = slice['slice_id'] slice_person_ids = slice['person_ids'] # the common set of attributes for our calls to GetPersons person_fields = ['person_id','email','hrn'] # for the intended set of hrns, locate existing persons target_hrns = [ user['hrn'] for user in users ] target_existing_persons = self.driver.shell.GetPersons ({'peer_id':None, 'hrn': target_hrns}, person_fields) target_existing_person_ids = [ person ['person_id'] for person in target_existing_persons ] # find out the hrns that *do not* have a corresponding person existing_hrns = [ person['hrn'] for person in target_existing_persons ] tocreate_hrns = set (target_hrns) - set (existing_hrns) # create these target_created_person_ids = [ self.create_person_from_user (users_by_hrn[hrn], site_id) for hrn in tocreate_hrns ] # we can partition the persons of interest into one of these 3 classes add_person_ids = set(target_created_person_ids) | set(target_existing_person_ids) - set(slice_person_ids) keep_person_ids = set(target_existing_person_ids) & set(slice_person_ids) del_person_ids = set(slice_person_ids) - set(target_existing_person_ids) # delete for person_id in del_person_ids: self.driver.shell.DeletePersonFromSlice (person_id, slice_id) # about the last 2 sets, for managing keys, we need to trace back person_id -> user # and for this we need all the Person objects; we already have the target_existing ones # also we avoid issuing a call if possible target_created_persons = [] if not target_created_person_ids \ else self.driver.shell.GetPersons \ ({'peer_id':None, 'person_id':target_created_person_ids}, person_fields) persons_by_person_id = { person['person_id'] : person \ for person in target_existing_persons + target_created_persons } def user_by_person_id (person_id): person = persons_by_person_id [person_id] hrn = person ['hrn'] return users_by_hrn [hrn] persons_to_verify_keys = {} # add for person_id in add_person_ids: self.driver.shell.AddPersonToSlice(person_id, slice_id) persons_to_verify_keys[person_id] = user_by_person_id(person_id) # Update kept persons for person_id in keep_person_ids: persons_to_verify_keys[person_id] = user_by_person_id(person_id) self.verify_keys(persons_to_verify_keys, options) # return hrns of the newly added persons return [ persons_by_person_id[person_id]['hrn'] for person_id in add_person_ids ]
def verify_slice_leases(self, slice, rspec_requested_leases): leases = self.driver.shell.GetLeases({'name':slice['name'], 'clip':int(time.time())}, ['lease_id','name', 'hostname', 't_from', 't_until']) grain = self.driver.shell.GetLeaseGranularity() requested_leases = [] for lease in rspec_requested_leases: requested_lease = {} slice_hrn, _ = urn_to_hrn(lease['slice_id']) top_auth_hrn = top_auth(slice_hrn) site_hrn = '.'.join(slice_hrn.split('.')[:-1]) slice_part = slice_hrn.split('.')[-1] if top_auth_hrn == self.driver.hrn: login_base = slice_hrn.split('.')[-2][:12] else: login_base = hash_loginbase(site_hrn) slice_name = '_'.join([login_base, slice_part]) if slice_name != slice['name']: continue elif Xrn(lease['component_id']).get_authority_urn().split(':')[0] != self.driver.hrn: continue hostname = xrn_to_hostname(lease['component_id']) # fill the requested node with nitos ids requested_lease['name'] = slice['name'] requested_lease['hostname'] = hostname requested_lease['t_from'] = int(lease['start_time']) requested_lease['t_until'] = int(lease['duration']) * grain + int(lease['start_time']) requested_leases.append(requested_lease) # prepare actual slice leases by lease_id leases_by_id = {} for lease in leases: leases_by_id[lease['lease_id']] = {'name': lease['name'], 'hostname': lease['hostname'], \ 't_from': lease['t_from'], 't_until': lease['t_until']} added_leases = [] kept_leases_id = [] deleted_leases_id = [] for lease_id in leases_by_id: if leases_by_id[lease_id] not in requested_leases: deleted_leases_id.append(lease_id) else: kept_leases_id.append(lease_id) requested_leases.remove(leases_by_id[lease_id]) added_leases = requested_leases try: self.driver.shell.DeleteLeases(deleted_leases_id) for lease in added_leases: self.driver.shell.AddLeases(lease['hostname'], slice['name'], lease['t_from'], lease['t_until']) except: logger.log_exc('Failed to add/remove slice leases') return leases
def verify_persons(self, slice_hrn, slice_record, users, sfa_peer, options={}): top_auth_hrn = top_auth(slice_hrn) site_hrn = '.'.join(slice_hrn.split('.')[:-1]) slice_part = slice_hrn.split('.')[-1] users_by_hrn = {} for user in users: user['hrn'], _ = urn_to_hrn(user['urn']) users_by_hrn[user['hrn']] = user if top_auth_hrn == self.driver.hrn: login_base = slice_hrn.split('.')[-2][:12] else: login_base = hash_loginbase(site_hrn) slice_name = '_'.join([login_base, slice_part]) persons = self.driver.shell.GetPersons({'peer_id': None}, ['person_id', 'email', 'hrn']) sites = self.driver.shell.GetSites({'peer_id': None}, [ 'node_ids', 'site_id', 'name', 'person_ids', 'slice_ids', 'login_base', 'hrn' ]) site = [site for site in sites if site['hrn'] == site_hrn][0] slices = self.driver.shell.GetSlices({'peer_id': None}, [ 'slice_id', 'node_ids', 'person_ids', 'expires', 'site_id', 'name', 'hrn' ]) slice = [slice for slice in slices if slice['hrn'] == slice_hrn][0] slice_persons = self.driver.shell.GetPersons( { 'peer_id': None, 'person_id': slice['person_ids'] }, ['person_id', 'email', 'hrn']) persons_by_hrn = {} persons_by_email = {} for person in persons: persons_by_hrn[person['hrn']] = person persons_by_email[person['email']] = person slice_persons_by_hrn = {} for slice_person in slice_persons: slice_persons_by_hrn[slice_person['hrn']] = slice_person # sort persons by HRN persons_to_add = set(users_by_hrn.keys()).difference( slice_persons_by_hrn.keys()) persons_to_delete = set(slice_persons_by_hrn.keys()).difference( users_by_hrn.keys()) persons_to_keep = set(users_by_hrn.keys()).intersection( slice_persons_by_hrn.keys()) persons_to_verify_keys = {} # Add persons or add persons to slice for person_hrn in persons_to_add: person_email = users_by_hrn[person_hrn].get( 'email', "*****@*****.**" % person_hrn.split('.')[-1]) if person_email and person_email in persons_by_email.keys(): # check if the user already exist in PL person_id = persons_by_email[person_email]['person_id'] self.driver.shell.AddPersonToSlice(person_id, slice['slice_id']) persons_to_verify_keys[person_id] = users_by_hrn[person_hrn] else: person = { 'first_name': person_hrn, 'last_name': person_hrn, 'email': users_by_hrn[person_hrn].get( 'email', "*****@*****.**" % person_hrn.split('.')[-1]), } person_id = self.driver.shell.AddPerson(person) self.driver.shell.AddRoleToPerson('user', int(person_id)) # enable the account self.driver.shell.UpdatePerson(int(person_id), {'enabled': True}) self.driver.shell.SetPersonSfaCreated(int(person_id), 'True') self.driver.shell.AddPersonToSite(int(person_id), site['site_id']) self.driver.shell.AddPersonToSlice(int(person_id), slice['slice_id']) self.driver.shell.SetPersonHrn(int(person_id), person_hrn) # Add keys for key in users_by_hrn[person_hrn].get('keys', []): key = {'key': key, 'key_type': 'ssh'} self.driver.shell.AddPersonKey(person_id, key) # Delete persons from slice for person_hrn in persons_to_delete: person_id = slice_persons_by_hrn[person_hrn].get('person_id') slice_id = slice['slice_id'] self.driver.shell.DeletePersonFromSlice(person_id, slice_id) # Update kept persons for person_hrn in persons_to_keep: person_id = slice_persons_by_hrn[person_hrn].get('person_id') persons_to_verify_keys[person_id] = users_by_hrn[person_hrn] self.verify_keys(persons_to_verify_keys, options) return persons_to_add
def verify_slice_leases(self, slice, rspec_requested_leases): leases = self.driver.shell.GetLeases( { 'name': slice['name'], 'clip': int(time.time()) }, ['lease_id', 'name', 'hostname', 't_from', 't_until']) grain = self.driver.shell.GetLeaseGranularity() requested_leases = [] for lease in rspec_requested_leases: requested_lease = {} slice_hrn, _ = urn_to_hrn(lease['slice_id']) top_auth_hrn = top_auth(slice_hrn) site_hrn = '.'.join(slice_hrn.split('.')[:-1]) slice_part = slice_hrn.split('.')[-1] if top_auth_hrn == self.driver.hrn: login_base = slice_hrn.split('.')[-2][:12] else: login_base = hash_loginbase(site_hrn) slice_name = '_'.join([login_base, slice_part]) if slice_name != slice['name']: continue elif Xrn(lease['component_id']).get_authority_urn().split( ':')[0] != self.driver.hrn: continue hostname = xrn_to_hostname(lease['component_id']) # fill the requested node with nitos ids requested_lease['name'] = slice['name'] requested_lease['hostname'] = hostname requested_lease['t_from'] = int(lease['start_time']) requested_lease['t_until'] = int(lease['duration']) * grain + int( lease['start_time']) requested_leases.append(requested_lease) # prepare actual slice leases by lease_id leases_by_id = {} for lease in leases: leases_by_id[lease['lease_id']] = {'name': lease['name'], 'hostname': lease['hostname'], \ 't_from': lease['t_from'], 't_until': lease['t_until']} added_leases = [] kept_leases_id = [] deleted_leases_id = [] for lease_id in leases_by_id: if leases_by_id[lease_id] not in requested_leases: deleted_leases_id.append(lease_id) else: kept_leases_id.append(lease_id) requested_leases.remove(leases_by_id[lease_id]) added_leases = requested_leases try: self.driver.shell.DeleteLeases(deleted_leases_id) for lease in added_leases: self.driver.shell.AddLeases(lease['hostname'], slice['name'], lease['t_from'], lease['t_until']) except: logger.log_exc('Failed to add/remove slice leases') return leases