From: Scott Baker Date: Fri, 3 Oct 2008 00:44:37 +0000 (+0000) Subject: documentation updates X-Git-Tag: sfa-0.9-0@14641~836 X-Git-Url: http://git.onelab.eu/?p=sfa.git;a=commitdiff_plain;h=10e4f872f8a5880141b395c58456c55525b89100 documentation updates --- diff --git a/registry/addinitscript.py b/registry/addinitscript.py new file mode 100644 index 00000000..ea862904 --- /dev/null +++ b/registry/addinitscript.py @@ -0,0 +1,50 @@ +## +# A simple tool for adding an initscript via the PLCAPI. I couldn't find the +# obvious way to do this through the PL interface, so I wrote this utility to +# do it. +# +# It takes two command line parameters: an initscript name and the contents of +# the initscript. +# +# For example, +# addinitscript.py foo "echo test" +## + +import getopt +import sys +import tempfile + +from config import * + +def connect_shell(): + global pl_auth, shell + + # get PL account settings from config module + pl_auth = get_pl_auth() + + # connect to planetlab + if "Url" in pl_auth: + import remoteshell + shell = remoteshell.RemoteShell() + else: + import PLC.Shell + shell = PLC.Shell.Shell(globals = globals()) + +def main(): + connect_shell() + + if len(sys.argv)<3: + print "syntax: addinitscript.py name value" + sys.exit(-1) + + name = sys.argv[1] + value = sys.argv[2] + + fields={} + fields['enabled'] = True + fields['name'] = name + fields['script'] = value + shell.AddInitScript(pl_auth, fields) + +if __name__ == "__main__": + main() diff --git a/registry/createAuthority.py b/registry/createAuthority.py index 9260f28f..302eed19 100644 --- a/registry/createAuthority.py +++ b/registry/createAuthority.py @@ -1,3 +1,10 @@ +## +# Create an authority via the hierarchy module. +# +# This tool was most likely used during development and is deprecated by the +# import tool. +## + import getopt import sys diff --git a/registry/import.py b/registry/import.py index f7cc7259..122c76fe 100644 --- a/registry/import.py +++ b/registry/import.py @@ -1,3 +1,17 @@ +## +# Import PLC records into the Geni database. It is indended that this tool be +# run once to create Geni records that reflect the current state of the +# planetlab database. +# +# The import tool assumes that the existing PLC hierarchy should all be part +# of "planetlab.us" (see the root_auth and level1_auth variables below). +# +# Public keys are extracted from the users' SSH keys automatically and used to +# create GIDs. This is relatively experimental as a custom tool had to be +# written to perform conversion from SSH to OpenSSL format. It only supports +# RSA keys at this time, not DSA keys. +## + import getopt import sys import tempfile @@ -11,6 +25,9 @@ from misc import * shell = None +## +# Two authorities are specified: the root authority and the level1 authority. + root_auth = "planetlab" level1_auth = "planetlab.us" diff --git a/registry/nuke.py b/registry/nuke.py index 0763ce58..b9b2c883 100644 --- a/registry/nuke.py +++ b/registry/nuke.py @@ -1,3 +1,11 @@ +## +# Delete all the database records for Geni. This tool is used to clean out Geni +# records during testing. +# +# Authority info (maintained by the hierarchy module in a subdirectory tree) +# is not purged by this tool and may be deleted by a command like 'rm'. +## + import getopt import sys diff --git a/registry/registry.py b/registry/registry.py index 82b33691..47921a2f 100644 --- a/registry/registry.py +++ b/registry/registry.py @@ -474,7 +474,20 @@ class Registry(GeniServer): return True ## - # GENI API: update + # GENI API: Register + # + # Update an object in the registry. Currently, this only updates the + # PLC information associated with the record. The Geni fields (name, type, + # GID) are fixed. + # + # The record is expected to have the pl_info field filled in with the data + # that should be updated. + # + # TODO: The geni_info member of the record should be parsed and the pl_info + # adjusted as necessary (add/remove users from a slice, etc) + # + # @param cred credential string specifying rights of the caller + # @param record a record dictionary to be updated def update(self, cred, record_dict): self.decode_authentication(cred, "update") @@ -512,9 +525,17 @@ class Registry(GeniServer): else: raise UnknownGeniType(type) + ## + # List the records in an authority. The objectGID in the supplied credential + # should name the authority that will be listed. + # # TODO: List doesn't take an hrn and uses the hrn contained in the # objectGid of the credential. Does this mean the only way to list an - # authority is by having a credential for that authority? + # authority is by having a credential for that authority? + # + # @param cred credential string specifying rights of the caller + # + # @return list of record dictionaries def list(self, cred): self.decode_authentication(cred, "list") @@ -542,6 +563,17 @@ class Registry(GeniServer): return dict_list + ## + # Resolve a record. This is an internal version of the Resolve API call + # and returns records in record object format rather than dictionaries + # that may be sent over XMLRPC. + # + # @param type type of record to resolve (user | sa | ma | slice | node) + # @param name human readable name of object + # @param must_exist if True, throw an exception if no records are found + # + # @return a list of record objects, or an empty list [] + def resolve_raw(self, type, name, must_exist=True): auth_name = get_authority(name) @@ -565,6 +597,17 @@ class Registry(GeniServer): return good_records + ## + # GENI API: Resolve + # + # This is a wrapper around resolve_raw that converts records objects into + # dictionaries before returning them to the user. + # + # @param cred credential string authorizing the caller + # @param name human readable name to resolve + # + # @return a list of record dictionaries, or an empty list + def resolve(self, cred, name): self.decode_authentication(cred, "resolve") @@ -575,6 +618,17 @@ class Registry(GeniServer): return dicts + ## + # GENI API: get_gid + # + # Retrieve the GID for an object. This function looks up a record in the + # registry and returns the GID of the record if it exists. + # TODO: Is this function needed? It's a shortcut for Resolve() + # + # @param name hrn to look up + # + # @return the string representation of a GID object + def get_gid(self, name): self.verify_object_belongs_to_me(name) records = self.resolve_raw("*", name) @@ -584,6 +638,16 @@ class Registry(GeniServer): gid_string_list.append(gid.save_to_string(save_parents=True)) return gid_string_list + ## + # Determine tje rights that an object should have. The rights are entirely + # dependent on the type of the object. For example, users automatically + # get "refresh", "resolve", and "info". + # + # @param type the type of the object (user | sa | ma | slice | node) + # @param name human readable name of the object (not used at this time) + # + # @return RightList object containing rights + def determine_rights(self, type, name): rl = RightList() @@ -610,6 +674,23 @@ class Registry(GeniServer): return rl + ## + # GENI API: Get_self_credential + # + # Get_self_credential a degenerate version of get_credential used by a + # client to get his initial credential when he doesn't have one. This is + # the same as get_credential(..., cred=None,...). + # + # The registry ensures that the client is the principal that is named by + # (type, name) by comparing the public key in the record's GID to the + # private key used to encrypt the client-side of the HTTPS connection. Thus + # it is impossible for one principal to retrieve another principal's + # credential without having the appropriate private key. + # + # @param type type of object (user | slice | sa | ma | node + # @param name human readable name of object + # + # @return the string representation of a credential object def get_self_credential(self, type, name): self.verify_object_belongs_to_me(name) @@ -644,6 +725,19 @@ class Registry(GeniServer): return cred.save_to_string(save_parents=True) + ## + # GENI API: Get_credential + # + # Retrieve a credential for an object. + # + # If cred==None, then the behavior reverts to get_self_credential() + # + # @param cred credential object specifying rights of the caller + # @param type type of object (user | slice | sa | ma | node) + # @param name human readable name of object + # + # @return the string representation of a credental object + def get_credential(self, cred, type, name): if not cred: return get_self_credential(self, type, name) @@ -677,6 +771,20 @@ class Registry(GeniServer): return new_cred.save_to_string(save_parents=True) + ## + # GENI_API: Create_gid + # + # Create a new GID. For MAs and SAs that are physically located on the + # registry, this allows a owner/operator/PI to create a new GID and have it + # signed by his respective authority. + # + # @param cred credential of caller + # @param name hrn for new GID + # @param uuid unique identifier for new GID + # @param pkey_string public-key string (TODO: why is this a string and not a keypair object?) + # + # @return the string representation of a GID object + def create_gid(self, cred, name, uuid, pubkey_str): self.decode_authentication(cred, "getcredential") @@ -696,6 +804,18 @@ class Registry(GeniServer): # ------------------------------------------------------------------------ # Component Interface + ## + # Convert a PLC record into the slice information that will be stored in + # a ticket. There are two parts to this information: attributes and + # rspec. + # + # Attributes are non-resource items, such as keys and the initscript + # Rspec is a set of resource specifications + # + # @param record a record object + # + # @return a tuple (attrs, rspec) of dictionaries + def record_to_slice_info(self, record): # get the user keys from the slice @@ -735,6 +855,22 @@ class Registry(GeniServer): return (attributes, rspec) + ## + # GENI API: get_ticket + # + # Retrieve a ticket. This operation is currently implemented on the + # registry (see SFA, engineering decisions), and is not implemented on + # components. + # + # The ticket is filled in with information from the PLC database. This + # information includes resources, and attributes such as user keys and + # initscripts. + # + # @param cred credential string + # @param name name of the slice to retrieve a ticket for + # @param rspec resource specification dictionary + # + # @return the string representation of a ticket object def get_ticket(self, cred, name, rspec): self.decode_authentication(cred, "getticket")