from sfa.util.sfalogging import logger
from sfa.util.defaultdict import defaultdict
-from sfa.util.sfatime import utcparse
+from sfa.util.sfatime import utcparse, datetime_to_string, datetime_to_epoch
from sfa.util.xrn import hrn_to_urn, get_leaf, urn_to_sliver_id
from sfa.util.cache import Cache
# one would think the driver should not need to mess with the SFA db, but..
-from sfa.storage.table import SfaTable
+from sfa.storage.alchemy import dbsession
+from sfa.storage.model import RegRecord
# used to be used in get_ticket
#from sfa.trust.sfaticket import SfaTicket
import sfa.plc.peers as peers
from sfa.plc.plaggregate import PlAggregate
from sfa.plc.plslices import PlSlices
-from sfa.util.plxrn import slicename_to_hrn, hostname_to_hrn, hrn_to_pl_slicename, hrn_to_pl_login_base
+from sfa.util.plxrn import PlXrn, slicename_to_hrn, hostname_to_hrn, hrn_to_pl_slicename
def list_to_dict(recs, key):
########## registry oriented
########################################
- ########## disabled users
- def is_enabled (self, record):
- # the incoming record was augmented already, so 'enabled' should be set
- if record['type'] == 'user':
- return record['enabled']
- # only users can be disabled
- return True
-
def augment_records_with_testbed_info (self, sfa_records):
return self.fill_record_info (sfa_records)
pointer = slices[0]['slice_id']
elif type == 'user':
- persons = self.shell.GetPersons([sfa_record['email']])
+ persons = self.shell.GetPersons({'email':sfa_record['email']})
if not persons:
+ for key in ['first_name','last_name']:
+ if key not in sfa_record: sfa_record[key]='*from*sfa*'
pointer = self.shell.AddPerson(dict(sfa_record))
else:
pointer = persons[0]['person_id']
self.shell.AddPersonToSite(pointer, login_base)
# What roles should this user have?
- self.shell.AddRoleToPerson('user', pointer)
+ roles=[]
+ if 'roles' in sfa_record:
+ # if specified in xml, but only low-level roles
+ roles = [ role for role in sfa_record['roles'] if role in ['user','tech'] ]
+ # at least user if no other cluse could be found
+ if not roles:
+ roles=['user']
+ for role in roles:
+ self.shell.AddRoleToPerson(role, pointer)
# Add the user's key
if pub_key:
self.shell.AddPersonKey(pointer, {'key_type' : 'ssh', 'key' : pub_key})
elif type == 'node':
- login_base = hrn_to_pl_login_base(sfa_record['authority'])
+ login_base = PlXrn(xrn=sfa_record['authority'],type='node').pl_login_base()
nodes = self.shell.GetNodes([pl_record['hostname']])
if not nodes:
pointer = self.shell.AddNode(login_base, pl_record)
##
- # Convert SFA fields to PLC fields for use when registering up updating
+ # Convert SFA fields to PLC fields for use when registering or updating
# registry record in the PLC database
#
pl_record["url"] = sfa_record["url"]
if "description" in sfa_record:
pl_record["description"] = sfa_record["description"]
- if "expires" in sfa_record:
- pl_record["expires"] = int(sfa_record["expires"])
+ if "expires" in sfa_record:
+ date = utcparse(sfa_record['expires'])
+ expires = datetime_to_epoch(date)
+ pl_record["expires"] = expires
elif type == "node":
if not "hostname" in pl_record:
pl_record["model"] = "geni"
elif type == "authority":
- pl_record["login_base"] = hrn_to_pl_login_base(hrn)
+ pl_record["login_base"] = PlXrn(xrn=hrn,type='authority').pl_login_base()
if "name" not in sfa_record:
pl_record["name"] = hrn
if "abbreviated_name" not in sfa_record:
if site_id in sites]
site_hrns = [".".join([auth_hrn, lbase]) for lbase in login_bases]
record['sites'] = site_hrns
+
+ if 'expires' in record:
+ date = utcparse(record['expires'])
+ datestring = datetime_to_string(date)
+ record['expires'] = datestring
return records
# we'll replace pl ids (person_ids) with hrns from the sfa records
# we obtain
- # get the sfa records
- table = SfaTable()
+ # get the registry records
person_list, persons = [], {}
- person_list = table.find({'type': 'user', 'pointer': person_ids})
+ person_list = dbsession.query (RegRecord).filter(RegRecord.pointer.in_(person_ids))
# create a hrns keyed on the sfa record's pointer.
# Its possible for multiple records to have the same pointer so
# the dict's value will be a list of hrns.
persons = defaultdict(list)
for person in person_list:
- persons[person['pointer']].append(person)
+ persons[person.pointer].append(person)
# get the pl records
pl_person_list, pl_persons = [], {}
# continue
sfa_info = {}
type = record['type']
+ logger.info("fill_record_sfa_info - incoming record typed %s"%type)
if (type == "slice"):
# all slice users are researchers
record['geni_urn'] = hrn_to_urn(record['hrn'], 'slice')
record['PI'] = []
record['researcher'] = []
for person_id in record.get('person_ids', []):
- hrns = [person['hrn'] for person in persons[person_id]]
+ hrns = [person.hrn for person in persons[person_id]]
record['researcher'].extend(hrns)
# pis at the slice's site
pl_pis = site_pis[record['site_id']]
pi_ids = [pi['person_id'] for pi in pl_pis]
for person_id in pi_ids:
- hrns = [person['hrn'] for person in persons[person_id]]
+ hrns = [person.hrn for person in persons[person_id]]
record['PI'].extend(hrns)
record['geni_creator'] = record['PI']
elif (type.startswith("authority")):
record['url'] = None
+ logger.info("fill_record_sfa_info - authority xherex")
if record['pointer'] != -1:
record['PI'] = []
record['operator'] = []
if pointer not in persons or pointer not in pl_persons:
# this means there is not sfa or pl record for this user
continue
- hrns = [person['hrn'] for person in persons[pointer]]
+ hrns = [person.hrn for person in persons[pointer]]
roles = pl_persons[pointer]['roles']
if 'pi' in roles:
record['PI'].extend(hrns)
# xxx TODO: URI, LatLong, IP, DNS
elif (type == "user"):
+ logger.info('setting user.email')
sfa_info['email'] = record.get("email", "")
sfa_info['geni_urn'] = hrn_to_urn(record['hrn'], 'user')
sfa_info['geni_certificate'] = record['gid']
####################
# plcapi works by changes, compute what needs to be added/deleted
- def update_relation (self, subject_type, target_type, subject_id, target_ids):
+ def update_relation (self, subject_type, target_type, relation_name, subject_id, target_ids):
# hard-wire the code for slice/user for now, could be smarter if needed
- if subject_type =='slice' and target_type == 'user':
+ if subject_type =='slice' and target_type == 'user' and relation_name == 'researcher':
subject=self.shell.GetSlices (subject_id)[0]
current_target_ids = subject['person_ids']
add_target_ids = list ( set (target_ids).difference(current_target_ids))
for target_id in del_target_ids:
logger.debug ("del_target_id = %s (type=%s)"%(target_id,type(target_id)))
self.shell.DeletePersonFromSlice (target_id, subject_id)
+ elif subject_type == 'authority' and target_type == 'user' and relation_name == 'pi':
+ # due to the plcapi limitations this means essentially adding pi role to all people in the list
+ # it's tricky to remove any pi role here, although it might be desirable
+ persons = self.shell.GetPersons (target_ids)
+ for person in persons:
+ if 'pi' not in person['roles']:
+ self.shell.AddRoleToPerson('pi',person['person_id'])
else:
- logger.info('unexpected relation to maintain, %s -> %s'%(subject_type,target_type))
+ logger.info('unexpected relation %s to maintain, %s -> %s'%(relation_name,subject_type,target_type))
########################################
# report about the local nodes only
nodes = self.shell.GetNodes({'node_id':slice['node_ids'],'peer_id':None},
['node_id', 'hostname', 'site_id', 'boot_state', 'last_contact'])
+
+ if len(nodes) == 0:
+ raise SliverDoesNotExist("You have not allocated any slivers here")
+
+ # get login info
+ user = {}
+ if slice['person_ids']:
+ persons = self.shell.GetPersons(slice['person_ids'], ['key_ids'])
+ key_ids = [key_id for person in persons for key_id in person['key_ids']]
+ person_keys = self.shell.GetKeys(key_ids)
+ keys = [key['key'] for key in keys]
+
+ user.update({'urn': slice_urn,
+ 'login': slice['name'],
+ 'protocol': ['ssh'],
+ 'port': ['22'],
+ 'keys': keys})
+
site_ids = [node['site_id'] for node in nodes]
result = {}
top_level_status = 'ready'
result['geni_urn'] = slice_urn
result['pl_login'] = slice['name']
- result['pl_expires'] = datetime.datetime.fromtimestamp(slice['expires']).ctime()
+ result['pl_expires'] = datetime_to_string(utcparse(slice['expires']))
+ result['geni_expires'] = datetime_to_string(utcparse(slice['expires']))
resources = []
for node in nodes:
res['pl_hostname'] = node['hostname']
res['pl_boot_state'] = node['boot_state']
res['pl_last_contact'] = node['last_contact']
+ res['geni_expires'] = datetime_to_string(utcparse(slice['expires']))
if node['last_contact'] is not None:
- res['pl_last_contact'] = datetime.datetime.fromtimestamp(node['last_contact']).ctime()
- sliver_id = urn_to_sliver_id(slice_urn, slice['slice_id'], node['node_id'])
+
+ res['pl_last_contact'] = datetime_to_string(utcparse(node['last_contact']))
+ sliver_id = urn_to_sliver_id(slice_urn, slice['slice_id'], node['node_id'], authority=self.hrn)
res['geni_urn'] = sliver_id
if node['boot_state'] == 'boot':
res['geni_status'] = 'ready'
top_level_status = 'failed'
res['geni_error'] = ''
+ res['users'] = [user]
resources.append(res)
slices.verify_slice_attributes(slice, requested_attributes, options=options)
# add/remove slice from nodes
- requested_slivers = [node.get('component_name') for node in rspec.version.get_nodes_with_slivers()]
+ requested_slivers = []
+ for node in rspec.version.get_nodes_with_slivers():
+ hostname = None
+ if node.get('component_name'):
+ hostname = node.get('component_name')
+ elif node.get('component_id'):
+ hostname = xrn_to_hostname(node.get('component_id'))
+ if hostname:
+ requested_slivers.append(hostname)
nodes = slices.verify_slice_nodes(slice, requested_slivers, peer)
# add/remove links links
raise RecordNotFound(slice_hrn)
slice = slices[0]
requested_time = utcparse(expiration_time)
- record = {'expires': int(time.mktime(requested_time.timetuple()))}
+ record = {'expires': int(datetime_to_epoch(requested_time))}
try:
self.shell.UpdateSlice(slice['slice_id'], record)
return True