add slice id to geniticket; create geni slices as delegated by default
[sfa.git] / plc / plc.py
index 8dae48c..a9391e7 100644 (file)
@@ -1,11 +1,12 @@
 ##
-# Geni Registry Wrapper
+# Geni PLC Wrapper
 #
-# This wrapper implements the Geni Registry.
+# This wrapper implements the Geni Registry and Slice Interfaces on PLC.
 #
-# There are several items that need to be done before starting the registry.
+# There are several items that need to be done before starting the wrapper
+# server.
 #
-# 1) Update util/config.py to match the parameters of your PLC installation. 
+# 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.
@@ -57,7 +58,7 @@ def geni_fields_to_pl_fields(type, hrn, geni_fields, pl_fields):
 
     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:
@@ -88,10 +89,7 @@ def geni_fields_to_pl_fields(type, hrn, geni_fields, 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):
     ##
@@ -143,8 +141,13 @@ class Registry(GeniServer):
         self.server.register_function(self.update)
         self.server.register_function(self.list)
         self.server.register_function(self.resolve)
-        # component interface
+        
+        # slice interface
         self.server.register_function(self.get_ticket)
+        self.server.register_function(self.start_slice)
+        self.server.register_function(self.stop_slice)
+        self.server.register_function(self.reset_slice)
+        self.server.register_function(self.delete_slice)
 
     ##
     # Given an authority name, return the information for that authority. This
@@ -238,6 +241,7 @@ class Registry(GeniServer):
         # 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"):
@@ -538,7 +542,17 @@ class Registry(GeniServer):
             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())
@@ -823,7 +837,10 @@ class Registry(GeniServer):
         return gid.save_to_string(save_parents=True)
 
     # ------------------------------------------------------------------------
-    # Component Interface
+    # Slice Interface
+    #
+    # All but get_ticket are currently stubbed out
+    #
 
     ##
     # Convert a PLC record into the slice information that will be stored in
@@ -853,6 +870,7 @@ class Registry(GeniServer):
         attributes['instantiation'] = record.pl_info['instantiation']
         attributes['vref'] = 'default'
         attributes['timestamp'] = time.time()
+        attributes['slice_id'] = record.pl_info['slice_id']
 
         rspec = {}
 
@@ -879,8 +897,8 @@ class Registry(GeniServer):
     ##
     # GENI API: get_ticket
     #
-    # Retrieve a ticket. This operation is currently implemented on the
-    # registry (see SFA, engineering decisions), and is not implemented on
+    # Retrieve a ticket. This operation is currently implemented on PLC
+    # only (see SFA, engineering decisions); it is not implemented on
     # components.
     #
     # The ticket is filled in with information from the PLC database. This
@@ -930,6 +948,59 @@ class Registry(GeniServer):
 
         return new_ticket.save_to_string(save_parents=True)
 
+    ##
+    # GENI API: stop_slice
+    #
+    # Stop a slice.
+    #
+    # @param cred a credential identifying the caller (callerGID) and the slice
+    #     (objectGID)
+
+    def stop_slice(self, cred_str):
+        self.decode_authentication(cred_str, "stopslice")
+        slicename = hrn_to_pl_slicename(self.object_gid.get_hrn())
+        # TODO: stop the slice
+
+    ##
+    # GENI API: start_slice
+    #
+    # Start a slice.
+    #
+    # @param cred a credential identifying the caller (callerGID) and the slice
+    #     (objectGID)
+
+    def start_slice(self, cred_str):
+        self.decode_authentication(cred_str, "startslice")
+        slicename = hrn_to_pl_slicename(self.object_gid.get_hrn())
+        # TODO: start the slice
+
+    ##
+    # GENI API: reset_slice
+    #
+    # Reset a slice.
+    #
+    # @param cred a credential identifying the caller (callerGID) and the slice
+    #     (objectGID)
+
+    def reset_slice(self, cred_str):
+        self.decode_authentication(cred_str, "resetslice")
+        slicename = hrn_to_pl_slicename(self.object_gid.get_hrn())
+        # TODO: reset the slice
+
+    ##
+    # GENI API: delete_slice
+    #
+    # Delete a slice.
+    #
+    # @param cred a credential identifying the caller (callerGID) and the slice
+    #     (objectGID)
+
+    def delete_slice(self, cred_str):
+        self.decode_authentication(cred_str, "deleteslice")
+        slicename = hrn_to_pl_slicename(self.object_gid.get_hrn())
+        # TODO: delete the slice
+
+
 
 if __name__ == "__main__":
     global AuthHierarchy