from sfa.util.prefixTree import prefixTree
from sfa.util.record import SfaRecord
from sfa.util.table import SfaTable
-from sfa.util.xrn import Xrn, get_leaf, get_authority, hrn_to_urn, urn_to_hrn
+from sfa.util.xrn import Xrn, get_authority, hrn_to_urn, urn_to_hrn
from sfa.util.plxrn import hrn_to_pl_login_base
from sfa.util.version import version_core
# verify_cancreate_credential requires that the member lists
# (researchers, pis, etc) be filled in
- api.driver.fill_record_info(record, api.aggregates)
- if record['type']=='user':
- if not record['enabled']:
+ if not api.driver.is_enabled_entity (record, api.aggregates):
raise AccountNotEnabled(": PlanetLab account %s is not enabled. Please contact your site PI" %(record['email']))
# get the callers gid
def Resolve(self, api, xrns, type=None, full=True):
- # load all known registry names into a prefix tree and attempt to find
- # the longest matching prefix
if not isinstance(xrns, types.ListType):
+ xrns = [xrns]
+ # try to infer type if not set and we get a single input
if not type:
type = Xrn(xrns).get_type()
- xrns = [xrns]
hrns = [urn_to_hrn(xrn)[0] for xrn in xrns]
+ # load all known registry names into a prefix tree and attempt to find
+ # the longest matching prefix
# create a dict where key is a registry hrn and its value is a
# hrns at that registry (determined by the known prefix tree).
xrn_dict = {}
records.extend([SfaRecord(dict=record).as_dict() for record in peer_records])
# try resolving the remaining unfound records at the local registry
- remaining_hrns = set(hrns).difference([record['hrn'] for record in records])
- # convert set to list
- remaining_hrns = [hrn for hrn in remaining_hrns]
+ local_hrns = list ( set(hrns).difference([record['hrn'] for record in records]) )
+ #
table = SfaTable()
- local_records = table.findObjects({'hrn': remaining_hrns})
+ local_records = table.findObjects({'hrn': local_hrns})
+ # xxx driver todo
if full:
api.driver.fill_record_info(local_records, api.aggregates)
# convert local record objects to dicts
records.extend([dict(record) for record in local_records])
- if not records:
- raise RecordNotFound(str(hrns))
-
if type:
records = filter(lambda rec: rec['type'] in [type], records)
+ if not records:
+ raise RecordNotFound(str(hrns))
+
return records
def List(self, api, xrn, origin_hrn=None):
record = SfaRecord(dict = record)
record['authority'] = get_authority(record['hrn'])
- type = record['type']
- hrn = record['hrn']
auth_info = api.auth.get_auth_info(record['authority'])
pub_key = None
# make sure record has a gid
# get the GID from the newly created authority
gid = auth_info.get_gid_object()
record.set_gid(gid.save_to_string(save_parents=True))
- pl_record = api.driver.sfa_fields_to_pl_fields(type, hrn, record)
- sites = api.driver.GetSites([pl_record['login_base']])
- if not sites:
- pointer = api.driver.AddSite(pl_record)
- else:
- pointer = sites[0]['site_id']
-
- record.set_pointer(pointer)
- record['pointer'] = pointer
+ pointer = api.driver.register (hrn, record, pub_key)
elif (type == "slice"):
- acceptable_fields=['url', 'instantiation', 'name', 'description']
- pl_record = api.driver.sfa_fields_to_pl_fields(type, hrn, record)
- for key in pl_record.keys():
- if key not in acceptable_fields:
- pl_record.pop(key)
- slices = api.driver.GetSlices([pl_record['name']])
- if not slices:
- pointer = api.driver.AddSlice(pl_record)
- else:
- pointer = slices[0]['slice_id']
- record.set_pointer(pointer)
- record['pointer'] = pointer
+ pointer = api.driver.register (hrn, record, pub_key)
elif (type == "user"):
- persons = api.driver.GetPersons([record['email']])
- if not persons:
- pointer = api.driver.AddPerson(dict(record))
- else:
- pointer = persons[0]['person_id']
-
- if 'enabled' in record and record['enabled']:
- api.driver.UpdatePerson(pointer, {'enabled': record['enabled']})
- # add this persons to the site only if he is being added for the first
- # time by sfa and doesont already exist in plc
- if not persons or not persons[0]['site_ids']:
- login_base = get_leaf(record['authority'])
- api.driver.AddPersonToSite(pointer, login_base)
-
- # What roles should this user have?
- api.driver.AddRoleToPerson('user', pointer)
- # Add the user's key
- if pub_key:
- api.driver.AddPersonKey(pointer, {'key_type' : 'ssh', 'key' : pub_key})
+ pointer = api.driver.register (hrn, record, pub_key)
elif (type == "node"):
- pl_record = api.driver.sfa_fields_to_pl_fields(type, hrn, record)
- login_base = hrn_to_pl_login_base(record['authority'])
- nodes = api.driver.GetNodes([pl_record['hostname']])
- if not nodes:
- pointer = api.driver.AddNode(login_base, pl_record)
- else:
- pointer = nodes[0]['node_id']
-
- record['pointer'] = pointer
+ pointer = api.driver.register (hrn, record, pub_key)
+
record.set_pointer(pointer)
record_id = table.insert(record)
record['record_id'] = record_id
from sfa.util.table import SfaTable
from sfa.util.defaultdict import defaultdict
-from sfa.util.xrn import hrn_to_urn
+from sfa.util.xrn import hrn_to_urn, get_leaf
from sfa.util.plxrn import slicename_to_hrn, hostname_to_hrn, hrn_to_pl_slicename, hrn_to_pl_login_base
+# the driver interface, mostly provides default behaviours
+from sfa.managers.driver import Driver
+
from sfa.plc.plshell import PlShell
def list_to_dict(recs, key):
keys = [rec[key] for rec in recs]
return dict(zip(keys, recs))
-class PlDriver (PlShell):
+#
+# inheriting Driver is not very helpful in the PL case but
+# makes sense in the general case
+#
+# PlShell is just an xmlrpc serverproxy where methods
+# can be sent as-is; it takes care of authentication
+# from the global config
+#
+# so OTOH we inherit PlShell just so one can do driver.GetNodes
+# which would not make much sense in the context of other testbeds
+# so ultimately PlDriver might just as well drop the PlShell inheritance
+#
+class PlDriver (Driver, PlShell):
def __init__ (self, config):
PlShell.__init__ (self, config)
assert (rspec_type == 'pl' or rspec_type == 'vini' or \
rspec_type == 'eucalyptus' or rspec_type == 'max')
+ ########## disabled users
+ def is_enabled_entity (self, record, aggregates):
+ self.fill_record_info(record, api.aggregates)
+ if record['type'] == 'user':
+ return record['enabled']
+ # only users can be disabled
+ return True
+
+ ##########
+ def register (self, hrn, sfa_record, pub_key):
+ type = sfa_record['type']
+ pl_record = self.sfa_fields_to_pl_fields(type, hrn, sfa_record)
+
+ if type == 'authority':
+ sites = self.GetSites([pl_record['login_base']])
+ if not sites:
+ pointer = self.AddSite(pl_record)
+ else:
+ pointer = sites[0]['site_id']
+
+ elif type == 'slice':
+ acceptable_fields=['url', 'instantiation', 'name', 'description']
+ for key in pl_record.keys():
+ if key not in acceptable_fields:
+ pl_record.pop(key)
+ slices = self.GetSlices([pl_record['name']])
+ if not slices:
+ pointer = self.AddSlice(pl_record)
+ else:
+ pointer = slices[0]['slice_id']
+
+ elif type == 'user':
+ persons = self.GetPersons([sfa_record['email']])
+ if not persons:
+ pointer = self.AddPerson(dict(sfa_record))
+ else:
+ pointer = persons[0]['person_id']
+
+ if 'enabled' in sfa_record and sfa_record['enabled']:
+ self.UpdatePerson(pointer, {'enabled': sfa_record['enabled']})
+ # add this person to the site only if she is being added for the first
+ # time by sfa and doesont already exist in plc
+ if not persons or not persons[0]['site_ids']:
+ login_base = get_leaf(sfa_record['authority'])
+ self.AddPersonToSite(pointer, login_base)
+
+ # What roles should this user have?
+ self.AddRoleToPerson('user', pointer)
+ # Add the user's key
+ if pub_key:
+ self.AddPersonKey(pointer, {'key_type' : 'ssh', 'key' : pub_key})
+
+ elif type == 'node':
+ login_base = hrn_to_pl_login_base(sfa_record['authority'])
+ nodes = api.driver.GetNodes([pl_record['hostname']])
+ if not nodes:
+ pointer = api.driver.AddNode(login_base, pl_record)
+ else:
+ pointer = nodes[0]['node_id']
+
+ return pointer
+
+
##
# Convert SFA fields to PLC fields for use when registering up updating
# registry record in the PLC database
#
- # @param type type of record (user, slice, ...)
- # @param hrn human readable name
- # @param sfa_fields dictionary of SFA fields
- # @param pl_fields dictionary of PLC fields (output)
-
- def sfa_fields_to_pl_fields(self, type, hrn, record):
- def convert_ints(tmpdict, int_fields):
- for field in int_fields:
- if field in tmpdict:
- tmpdict[field] = int(tmpdict[field])
+ def sfa_fields_to_pl_fields(self, type, hrn, sfa_record):
pl_record = {}
- #for field in record:
- # pl_record[field] = record[field]
if type == "slice":
- if not "instantiation" in pl_record:
- pl_record["instantiation"] = "plc-instantiated"
pl_record["name"] = hrn_to_pl_slicename(hrn)
- if "url" in record:
- pl_record["url"] = record["url"]
- if "description" in record:
- pl_record["description"] = record["description"]
- if "expires" in record:
- pl_record["expires"] = int(record["expires"])
+ if "instantiation" in sfa_record:
+ pl_record['instantiation']=sfa_record['instantiation']
+ else:
+ pl_record["instantiation"] = "plc-instantiated"
+ if "url" in sfa_record:
+ 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"])
elif type == "node":
if not "hostname" in pl_record:
- if not "hostname" in record:
+ # fetch from sfa_record
+ if "hostname" not in sfa_record:
raise MissingSfaInfo("hostname")
- pl_record["hostname"] = record["hostname"]
- if not "model" in pl_record:
+ pl_record["hostname"] = sfa_record["hostname"]
+ if "model" in sfa_record:
+ pl_record["model"] = sfa_record["model"]
+ else:
pl_record["model"] = "geni"
elif type == "authority":
pl_record["login_base"] = hrn_to_pl_login_base(hrn)
-
- if not "name" in pl_record:
+ if "name" not in sfa_record:
pl_record["name"] = hrn
-
- if not "abbreviated_name" in pl_record:
+ if "abbreviated_name" not in sfa_record:
pl_record["abbreviated_name"] = hrn
-
- if not "enabled" in pl_record:
+ if "enabled" not in sfa_record:
pl_record["enabled"] = True
-
- if not "is_public" in pl_record:
+ if "is_public" not in sfa_record:
pl_record["is_public"] = True
return pl_record
+ ####################
+ def fill_record_info(self, records, aggregates):
+ """
+ Given a (list of) SFA record, fill in the PLC specific
+ and SFA specific fields in the record.
+ """
+ if not isinstance(records, list):
+ records = [records]
+
+ self.fill_record_pl_info(records)
+ self.fill_record_sfa_info(records, aggregates)
+
def fill_record_pl_info(self, records):
"""
Fill in the planetlab specific fields of a SFA record. This
person_list, persons = [], {}
person_list = table.find({'type': 'user', 'pointer': person_ids})
# create a hrns keyed on the sfa record's pointer.
- # Its possible for multiple records to have the same pointer so
+ # 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:
# xxx TODO: PostalAddress, Phone
record.update(sfa_info)
- def fill_record_info(self, records, aggregates):
- """
- Given a SFA record, fill in the PLC specific and SFA specific
- fields in the record.
- """
- if not isinstance(records, list):
- records = [records]
-
- self.fill_record_pl_info(records)
- self.fill_record_sfa_info(records, aggregates)
+ ####################
+ def update_membership(self, oldRecord, record):
+ if record.type == "slice":
+ self.update_membership_list(oldRecord, record, 'researcher',
+ self.AddPersonToSlice,
+ self.DeletePersonFromSlice)
+ elif record.type == "authority":
+ # xxx TODO
+ pass
def update_membership_list(self, oldRecord, record, listName, addFunc, delFunc):
# get a list of the HRNs that are members of the old and new records
for personId in oldIdList:
if not (personId in newIdList):
delFunc(personId, containerId)
-
- def update_membership(self, oldRecord, record):
- if record.type == "slice":
- self.update_membership_list(oldRecord, record, 'researcher',
- self.AddPersonToSlice,
- self.DeletePersonFromSlice)
- elif record.type == "authority":
- # xxx TODO
- pass