##
-# Geni Registry Wrapper
-#
-# This wrapper implements the Geni Registry.
-#
-# There are several items that need to be done before starting the registry.
-#
-# 1) Update util/config.py to match the parameters of your PLC installation.
-#
-# 2) Import the existing planetlab database, creating the
-# appropriate geni records. This is done by running the "import.py" tool.
-#
-# 3) Create a "trusted_roots" directory and place the certificate of the root
-# authority in that directory. Given the defaults in import.py, this certificate
-# would be named "planetlab.gid". For example,
-#
-# mkdir trusted_roots; cp authorities/planetlab.gid trusted_roots/
-##
+# Registry is a GeniServer that implements the Registry interface
import tempfile
import os
import time
import sys
-from cert import *
-from gid import *
-from geniserver import *
-from excep import *
-from trustedroot import *
-from hierarchy import *
-from misc import *
-from record import *
-from genitable import *
-from geniticket import *
+from util.credential import Credential
+from util.hierarchy import Hierarchy
+from util.trustedroot import TrustedRootList
+from util.cert import Keypair, Certificate
+from util.gid import GID
+from util.geniserver import GeniServer
+from util.record import GeniRecord
+from util.rights import RightList
+from util.genitable import GeniTable
+from util.geniticket import Ticket
+from util.excep import *
+from util.misc import *
+
+from util.config import *
##
# Convert geni fields to PLC fields for use when registering up updating
elif type == "slice":
if not "instantiation" in pl_fields:
- pl_fields["instantiation"] = "plc-instantiated"
+ pl_fields["instantiation"] = "delegated" # "plc-instantiated"
if not "name" in pl_fields:
pl_fields["name"] = hrn_to_pl_slicename(hrn)
if not "max_nodes" in pl_fields:
pl_fields["is_public"] = True
##
-# Registry is a GeniServer that serves registry requests. It also serves
-# component and slice operations that are implemented on the registry
-# due to SFA engineering decisions
-#
+# Registry is a GeniServer that serves registry and slice operations at PLC.
class Registry(GeniServer):
##
self.server.register_function(self.update)
self.server.register_function(self.list)
self.server.register_function(self.resolve)
- # component interface
- self.server.register_function(self.get_ticket)
##
# Given an authority name, return the information for that authority. This
# @param auth_hrn human readable name of authority
def get_auth_info(self, auth_hrn):
- return AuthHierarchy.get_auth_info(auth_hrn)
+ return self.hierarchy.get_auth_info(auth_hrn)
##
# Given an authority name, return the database table for that authority. If
# for example, the top level authority records which are
# authorities, but not PL "sites"
if pointer == -1:
+ record.set_pl_info({})
return
if (type == "sa") or (type == "ma"):
if (type == "sa") or (type=="ma"):
# update the tree
- if not AuthHierarchy.auth_exists(name):
- AuthHierarchy.create_auth(name)
+ if not self.hierarchy.auth_exists(name):
+ self.hierarchy.create_auth(name)
# authorities are special since they are managed by the registry
# rather than by the caller. We create our own GID for the
self.shell.UpdateSlice(self.pl_auth, pointer, record.get_pl_info())
elif type == "user":
- self.shell.UpdatePerson(self.pl_auth, pointer, record.get_pl_info())
+ # SMBAKER: UpdatePerson only allows a limited set of fields to be
+ # updated. Ideally we should have a more generic way of doing
+ # this. I copied the field names from UpdatePerson.py...
+ update_fields = {}
+ all_fields = record.get_pl_info()
+ for key in all_fields.keys():
+ if key in ['first_name', 'last_name', 'title', 'email',
+ 'password', 'phone', 'url', 'bio', 'accepted_aup',\r
+ 'enabled']:
+ update_fields[key] = all_fields[key]
+ self.shell.UpdatePerson(self.pl_auth, pointer, update_fields)
elif type == "node":
self.shell.UpdateNode(self.pl_auth, pointer, record.get_pl_info())
rl = self.determine_rights(type, name)
cred.set_privileges(rl)
- cred.set_parent(AuthHierarchy.get_auth_cred(auth_hrn))
+ cred.set_parent(self.hierarchy.get_auth_cred(auth_hrn))
cred.encode()
cred.sign()
rl = self.determine_rights(type, name)
new_cred.set_privileges(rl)
- new_cred.set_parent(AuthHierarchy.get_auth_cred(auth_hrn))
+ new_cred.set_parent(self.hierarchy.get_auth_cred(auth_hrn))
new_cred.encode()
new_cred.sign()
pkey = Keypair()
pkey.load_pubkey_from_string(pubkey_str)
- gid = AuthHierarchy.create_gid(name, uuid, pkey)
+ gid = self.hierarchy.create_gid(name, uuid, pkey)
return gid.save_to_string(save_parents=True)
- # ------------------------------------------------------------------------
- # 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
- keys = []
- persons = self.shell.GetPersons(self.pl_auth, record.pl_info['person_ids'])
- for person in persons:
- person_keys = self.shell.GetKeys(self.pl_auth, person["key_ids"])
- for person_key in person_keys:
- keys = keys + [person_key['key']]
-
- attributes={}
- attributes['name'] = record.pl_info['name']
- attributes['keys'] = keys
- attributes['instantiation'] = record.pl_info['instantiation']
- attributes['vref'] = 'default'
- attributes['timestamp'] = time.time()
-
- rspec = {}
-
- # get the PLC attributes and separate them into slice attributes and
- # rspec attributes
- filter = {}
- filter['slice_id'] = record.pl_info['slice_id']
- plc_attrs = self.shell.GetSliceAttributes(self.pl_auth, filter)
- for attr in plc_attrs:
- name = attr['name']
-
- # initscripts: lookup the contents of the initscript and store it
- # in the ticket attributes
- if (name == "initscript"):
- filter={'name': attr['value']}
- initscripts = self.shell.GetInitScripts(self.pl_auth, filter)
- if initscripts:
- attributes['initscript'] = initscripts[0]['script']
- else:
- rspec[name] = attr['value']
-
- 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")
-
- self.verify_object_belongs_to_me(name)
-
- self.verify_object_permission(name)
-
- # XXX much of this code looks like get_credential... are they so similar
- # that they should be combined?
-
- auth_hrn = get_authority(name)
- auth_info = self.get_auth_info(auth_hrn)
-
- records = self.resolve_raw("slice", name, must_exist=True)
- record = records[0]
-
- object_gid = record.get_gid_object()
- new_ticket = Ticket(subject = object_gid.get_subject())
- new_ticket.set_gid_caller(self.client_gid)
- new_ticket.set_gid_object(object_gid)
- new_ticket.set_issuer(key=auth_info.get_pkey_object(), subject=auth_hrn)
- new_ticket.set_pubkey(object_gid.get_pubkey())
-
- self.fill_record_info(record)
-
- (attributes, rspec) = self.record_to_slice_info(record)
-
- new_ticket.set_attributes(attributes)
- new_ticket.set_rspec(rspec)
-
- new_ticket.set_parent(AuthHierarchy.get_auth_ticket(auth_hrn))
-
- new_ticket.encode()
- new_ticket.sign()
-
- return new_ticket.save_to_string(save_parents=True)
-
-
-if __name__ == "__main__":
- global AuthHierarchy
- global TrustedRoots
-
- key_file = "server.key"
- cert_file = "server.cert"
-
- # if no key is specified, then make one up
- if (not os.path.exists(key_file)) or (not os.path.exists(cert_file)):
- key = Keypair(create=True)
- key.save_to_file(key_file)
-
- cert = Certificate(subject="registry")
- cert.set_issuer(key=key, subject="registry")
- cert.set_pubkey(key)
- cert.sign()
- cert.save_to_file(cert_file)
-
- AuthHierarchy = Hierarchy()
-
- TrustedRoots = TrustedRootList()
-
- s = Registry("", 12345, key_file, cert_file)
- s.trusted_cert_list = TrustedRoots.get_list()
- s.run()
-