Merge Master in geni-v3 conflict resolution
[sfa.git] / sfa / planetlab / pldriver.py
index e4330e8..4bcb793 100644 (file)
@@ -1,33 +1,31 @@
-import time
 import datetime
 #
 from sfa.util.faults import MissingSfaInfo, UnknownSfaType, \
 import datetime
 #
 from sfa.util.faults import MissingSfaInfo, UnknownSfaType, \
-    RecordNotFound, SfaNotImplemented, SliverDoesNotExist
-
+    RecordNotFound, SfaNotImplemented, SliverDoesNotExist, SearchFailed, \
+    UnsupportedOperation, Forbidden 
 from sfa.util.sfalogging import logger
 from sfa.util.defaultdict import defaultdict
 from sfa.util.sfatime import utcparse, datetime_to_string, datetime_to_epoch
 from sfa.util.sfalogging import logger
 from sfa.util.defaultdict import defaultdict
 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.xrn import Xrn, hrn_to_urn, get_leaf
 from sfa.util.cache import Cache
 
 # one would think the driver should not need to mess with the SFA db, but..
 from sfa.storage.alchemy import dbsession
 from sfa.util.cache import Cache
 
 # one would think the driver should not need to mess with the SFA db, but..
 from sfa.storage.alchemy import dbsession
-from sfa.storage.model import RegRecord
+from sfa.storage.model import RegRecord, SliverAllocation
+from sfa.trust.credential import Credential
 
 # used to be used in get_ticket
 #from sfa.trust.sfaticket import SfaTicket
 
 # used to be used in get_ticket
 #from sfa.trust.sfaticket import SfaTicket
-
 from sfa.rspecs.version_manager import VersionManager
 from sfa.rspecs.rspec import RSpec
 
 # the driver interface, mostly provides default behaviours
 from sfa.managers.driver import Driver
 from sfa.rspecs.version_manager import VersionManager
 from sfa.rspecs.rspec import RSpec
 
 # the driver interface, mostly provides default behaviours
 from sfa.managers.driver import Driver
-
 from sfa.planetlab.plshell import PlShell
 import sfa.planetlab.peers as peers
 from sfa.planetlab.plaggregate import PlAggregate
 from sfa.planetlab.plslices import PlSlices
 from sfa.planetlab.plshell import PlShell
 import sfa.planetlab.peers as peers
 from sfa.planetlab.plaggregate import PlAggregate
 from sfa.planetlab.plslices import PlSlices
-from sfa.planetlab.plxrn import PlXrn, slicename_to_hrn, hostname_to_hrn, hrn_to_pl_slicename
+from sfa.planetlab.plxrn import PlXrn, slicename_to_hrn, hostname_to_hrn, hrn_to_pl_slicename, xrn_to_hostname
 
 
 def list_to_dict(recs, key):
 
 
 def list_to_dict(recs, key):
@@ -55,7 +53,49 @@ class PlDriver (Driver):
             if PlDriver.cache is None:
                 PlDriver.cache = Cache()
             self.cache = PlDriver.cache
             if PlDriver.cache is None:
                 PlDriver.cache = Cache()
             self.cache = PlDriver.cache
+
+    def sliver_to_slice_xrn(self, xrn):
+        sliver_id_parts = Xrn(xrn).get_sliver_id_parts()
+        filter = {}
+        try:
+            filter['slice_id'] = int(sliver_id_parts[0])
+        except ValueError:
+            fliter['name'] = sliver_id_parts[0] 
+        slices = self.shell.GetSlices(filter)
+        if not slices:
+            raise Forbidden("Unable to locate slice record for sliver:  %s" % xrn)
+        slice = slices[0]
+        slice_xrn = PlXrn(auth=self.hrn, slicename=slice['name'])
+        return slice_xrn 
  
  
+    def check_sliver_credentials(self, creds, urns):
+        # build list of cred object hrns
+        slice_cred_names = []
+        for cred in creds:
+            slice_cred_hrn = Credential(cred=cred).get_gid_object().get_hrn() 
+            slice_cred_names.append(PlXrn(xrn=slice_cred_hrn).pl_slicename()) 
+
+        # look up slice name of slivers listed in urns arg
+        slice_ids = []
+        for urn in urns:
+            sliver_id_parts = Xrn(xrn=urn).get_sliver_id_parts()
+            try:
+                slice_ids.append(int(sliver_id_parts[0]))
+            except ValueError: 
+                pass
+
+        if not slice_ids:
+             raise Forbidden("sliver urn not provided")
+
+        slices = self.shell.GetSlices(slice_ids)
+        sliver_names = [slice['name'] for slice in slices]
+
+        # make sure we have a credential for every specified sliver ierd
+        for sliver_name in sliver_names:
+            if sliver_name not in slice_cred_names:
+                msg = "Valid credential not found for target: %s" % sliver_name
+                raise Forbidden(msg)
+
     ########################################
     ########## registry oriented
     ########################################
     ########################################
     ########## registry oriented
     ########################################
@@ -94,7 +134,10 @@ class PlDriver (Driver):
             if not persons:
                 for key in ['first_name','last_name']:
                     if key not in sfa_record: sfa_record[key]='*from*sfa*'
             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))
+                # AddPerson does not allow everything to be set
+                can_add = ['first_name', 'last_name', 'title','email', 'password', 'phone', 'url', 'bio']
+                add_person_dict=dict ( [ (k,sfa_record[k]) for k in sfa_record if k in can_add ] )
+                pointer = self.shell.AddPerson(add_person_dict)
             else:
                 pointer = persons[0]['person_id']
     
             else:
                 pointer = persons[0]['person_id']
     
@@ -121,7 +164,7 @@ class PlDriver (Driver):
                 self.shell.AddPersonKey(pointer, {'key_type' : 'ssh', 'key' : pub_key})
 
         elif type == 'node':
                 self.shell.AddPersonKey(pointer, {'key_type' : 'ssh', 'key' : pub_key})
 
         elif type == 'node':
-            login_base = PlXrn(xrn=sfa_record['authority'],type='node').pl_login_base()
+            login_base = PlXrn(xrn=sfa_record['authority'],type='authority').pl_login_base()
             nodes = self.shell.GetNodes([pl_record['hostname']])
             if not nodes:
                 pointer = self.shell.AddNode(login_base, pl_record)
             nodes = self.shell.GetNodes([pl_record['hostname']])
             if not nodes:
                 pointer = self.shell.AddNode(login_base, pl_record)
@@ -135,6 +178,7 @@ class PlDriver (Driver):
     def update (self, old_sfa_record, new_sfa_record, hrn, new_key):
         pointer = old_sfa_record['pointer']
         type = old_sfa_record['type']
     def update (self, old_sfa_record, new_sfa_record, hrn, new_key):
         pointer = old_sfa_record['pointer']
         type = old_sfa_record['type']
+        new_key_pointer = None
 
         # new_key implemented for users only
         if new_key and type not in [ 'user' ]:
 
         # new_key implemented for users only
         if new_key and type not in [ 'user' ]:
@@ -173,20 +217,19 @@ class PlDriver (Driver):
                 keys = person['key_ids']
                 keys = self.shell.GetKeys(person['key_ids'])
                 
                 keys = person['key_ids']
                 keys = self.shell.GetKeys(person['key_ids'])
                 
-                # Delete all stale keys
                 key_exists = False
                 for key in keys:
                 key_exists = False
                 for key in keys:
-                    if new_key != key['key']:
-                        self.shell.DeleteKey(key['key_id'])
-                    else:
+                    if new_key == key['key']:
                         key_exists = True
                         key_exists = True
+                        new_key_pointer = key['key_id']
+                        break
                 if not key_exists:
                 if not key_exists:
-                    self.shell.AddPersonKey(pointer, {'key_type': 'ssh', 'key': new_key})
+                    new_key_pointer = self.shell.AddPersonKey(pointer, {'key_type': 'ssh', 'key': new_key})
     
         elif type == "node":
             self.shell.UpdateNode(pointer, new_sfa_record)
 
     
         elif type == "node":
             self.shell.UpdateNode(pointer, new_sfa_record)
 
-        return True
+        return (pointer, new_key_pointer)
         
 
     ##########
         
 
     ##########
@@ -563,150 +606,34 @@ class PlDriver (Driver):
 
     def testbed_name (self): return "myplc"
 
 
     def testbed_name (self): return "myplc"
 
-    # 'geni_request_rspec_versions' and 'geni_ad_rspec_versions' are mandatory
     def aggregate_version (self):
     def aggregate_version (self):
-        version_manager = VersionManager()
-        ad_rspec_versions = []
-        request_rspec_versions = []
-        for rspec_version in version_manager.versions:
-            if rspec_version.content_type in ['*', 'ad']:
-                ad_rspec_versions.append(rspec_version.to_dict())
-            if rspec_version.content_type in ['*', 'request']:
-                request_rspec_versions.append(rspec_version.to_dict()) 
-        return {
-            'testbed':self.testbed_name(),
-            'geni_request_rspec_versions': request_rspec_versions,
-            'geni_ad_rspec_versions': ad_rspec_versions,
-            }
-
-    def list_slices (self, creds, options):
-        # look in cache first
-        if self.cache:
-            slices = self.cache.get('slices')
-            if slices:
-                logger.debug("PlDriver.list_slices returns from cache")
-                return slices
-    
-        # get data from db 
-        slices = self.shell.GetSlices({'peer_id': None}, ['name'])
-        slice_hrns = [slicename_to_hrn(self.hrn, slice['name']) for slice in slices]
-        slice_urns = [hrn_to_urn(slice_hrn, 'slice') for slice_hrn in slice_hrns]
-    
-        # cache the result
-        if self.cache:
-            logger.debug ("PlDriver.list_slices stores value in cache")
-            self.cache.add('slices', slice_urns) 
-    
-        return slice_urns
-        
+        return {}
+
     # first 2 args are None in case of resource discovery
     # first 2 args are None in case of resource discovery
-    def list_resources (self, slice_urn, slice_hrn, creds, options):
-        cached_requested = options.get('cached', True) 
-    
-        version_manager = VersionManager()
-        # get the rspec's return format from options
-        rspec_version = version_manager.get_version(options.get('geni_rspec_version'))
-        version_string = "rspec_%s" % (rspec_version)
-    
-        #panos adding the info option to the caching key (can be improved)
-        if options.get('info'):
-            version_string = version_string + "_"+options.get('info', 'default')
-    
-        # look in cache first
-        if cached_requested and self.cache and not slice_hrn:
-            rspec = self.cache.get(version_string)
-            if rspec:
-                logger.debug("PlDriver.ListResources: returning cached advertisement")
-                return rspec 
-    
-        #panos: passing user-defined options
-        #print "manager options = ",options
+    def list_resources (self, version=None, options={}):
         aggregate = PlAggregate(self)
         aggregate = PlAggregate(self)
-        rspec =  aggregate.get_rspec(slice_xrn=slice_urn, version=rspec_version, 
-                                     options=options)
-    
-        # cache the result
-        if self.cache and not slice_hrn:
-            logger.debug("PlDriver.ListResources: stores advertisement in cache")
-            self.cache.add(version_string, rspec)
-    
+        rspec =  aggregate.list_resources(version=version, options=options)
         return rspec
         return rspec
-    
-    def sliver_status (self, slice_urn, slice_hrn):
-        # find out where this slice is currently running
-        slicename = hrn_to_pl_slicename(slice_hrn)
-        
-        slices = self.shell.GetSlices([slicename], ['slice_id', 'node_ids','person_ids','name','expires'])
-        if len(slices) == 0:        
-            raise SliverDoesNotExist("%s (used %s as slicename internally)" % (slice_hrn, slicename))
-        slice = slices[0]
-        
-        # 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 = 'unknown'
-        if nodes:
-            top_level_status = 'ready'
-        result['geni_urn'] = slice_urn
-        result['pl_login'] = slice['name']
-        result['pl_expires'] = datetime_to_string(utcparse(slice['expires']))
-        result['geni_expires'] = datetime_to_string(utcparse(slice['expires']))
-        
-        resources = []
-        for node in nodes:
-            res = {}
-            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_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'
-            else:
-                res['geni_status'] = 'failed'
-                top_level_status = 'failed' 
-                
-            res['geni_error'] = ''
-            res['users'] = [user]  
-    
-            resources.append(res)
-            
-        result['geni_status'] = top_level_status
-        result['geni_resources'] = resources
-        return result
 
 
-    def create_sliver (self, slice_urn, slice_hrn, creds, rspec_string, users, options):
+    def describe(self, urns, version, options={}):
+        aggregate = PlAggregate(self)
+        return aggregate.describe(urns, version=version, options=options)
+    
+    def status (self, urns, options={}):
+        aggregate = PlAggregate(self)
+        desc =  aggregate.describe(urns)
+        status = {'geni_urn': desc['geni_urn'],
+                  'geni_slivers': desc['geni_slivers']}
+        return status
 
 
+    def allocate (self, urn, rspec_string, expiration, options={}):
+        xrn = Xrn(urn)
         aggregate = PlAggregate(self)
         slices = PlSlices(self)
         aggregate = PlAggregate(self)
         slices = PlSlices(self)
-        peer = slices.get_peer(slice_hrn)
-        sfa_peer = slices.get_sfa_peer(slice_hrn)
+        peer = slices.get_peer(xrn.get_hrn())
+        sfa_peer = slices.get_sfa_peer(xrn.get_hrn())
         slice_record=None    
         slice_record=None    
+        users = options.get('geni_users', [])
         if users:
             slice_record = users[0].get('slice_record', {})
     
         if users:
             slice_record = users[0].get('slice_record', {})
     
@@ -715,86 +642,128 @@ class PlDriver (Driver):
         requested_attributes = rspec.version.get_slice_attributes()
         
         # ensure site record exists
         requested_attributes = rspec.version.get_slice_attributes()
         
         # ensure site record exists
-        site = slices.verify_site(slice_hrn, slice_record, peer, sfa_peer, options=options)
+        site = slices.verify_site(xrn.hrn, slice_record, peer, sfa_peer, options=options)
         # ensure slice record exists
         # ensure slice record exists
-        slice = slices.verify_slice(slice_hrn, slice_record, peer, sfa_peer, options=options)
+        slice = slices.verify_slice(xrn.hrn, slice_record, peer, sfa_peer, expiration=expiration, options=options)
         # ensure person records exists
         # ensure person records exists
-        persons = slices.verify_persons(slice_hrn, slice, users, peer, sfa_peer, options=options)
+        #persons = slices.verify_persons(xrn.hrn, slice, users, peer, sfa_peer, options=options)
         # ensure slice attributes exists
         slices.verify_slice_attributes(slice, requested_attributes, options=options)
         # ensure slice attributes exists
         slices.verify_slice_attributes(slice, requested_attributes, options=options)
-        
+       
         # add/remove slice from nodes
         # add/remove slice from nodes
-        requested_slivers = []
-        for node in rspec.version.get_nodes_with_slivers():
-            hostname = None
-            if node.get('component_name'):
-                hostname = node.get('component_name').strip()
-            elif node.get('component_id'):
-                hostname = xrn_to_hostname(node.get('component_id').strip())
-            if hostname:
-                requested_slivers.append(hostname)
-        nodes = slices.verify_slice_nodes(slice, requested_slivers, peer) 
-   
+        request_nodes = rspec.version.get_nodes_with_slivers()
+        nodes = slices.verify_slice_nodes(urn, slice, request_nodes, peer)
+         
         # add/remove links links 
         slices.verify_slice_links(slice, rspec.version.get_link_requests(), nodes)
         # add/remove links links 
         slices.verify_slice_links(slice, rspec.version.get_link_requests(), nodes)
-    
+
+        # add/remove leases
+        try:
+           rspec_requested_leases = rspec.version.get_leases()
+           leases = slices.verify_slice_leases(slice, rspec_requested_leases, peer)
+        except:
+           pass
+
         # handle MyPLC peer association.
         # only used by plc and ple.
         # handle MyPLC peer association.
         # only used by plc and ple.
-        slices.handle_peer(site, slice, persons, peer)
+        slices.handle_peer(site, slice, None, peer)
         
         
-        return aggregate.get_rspec(slice_xrn=slice_urn, version=rspec.version)
+        return aggregate.describe([xrn.get_urn()], version=rspec.version)
 
 
-    def delete_sliver (self, slice_urn, slice_hrn, creds, options):
-        slicename = hrn_to_pl_slicename(slice_hrn)
-        slices = self.shell.GetSlices({'name': slicename})
-        if not slices:
-            return 1
-        slice = slices[0]
-    
-        # determine if this is a peer slice
-        # xxx I wonder if this would not need to use PlSlices.get_peer instead 
-        # in which case plc.peers could be deprecated as this here
-        # is the only/last call to this last method in plc.peers
-        peer = peers.get_peer(self, slice_hrn)
-        try:
-            if peer:
-                self.shell.UnBindObjectFromPeer('slice', slice['slice_id'], peer)
-            self.shell.DeleteSliceFromNodes(slicename, slice['node_ids'])
-        finally:
-            if peer:
-                self.shell.BindObjectToPeer('slice', slice['slice_id'], peer, slice['peer_slice_id'])
-        return 1
-    
-    def renew_sliver (self, slice_urn, slice_hrn, creds, expiration_time, options):
-        slicename = hrn_to_pl_slicename(slice_hrn)
-        slices = self.shell.GetSlices({'name': slicename}, ['slice_id'])
-        if not slices:
-            raise RecordNotFound(slice_hrn)
-        slice = slices[0]
+    def provision(self, urns, options={}):
+        # update users
+        slices = PlSlices(self)
+        aggregate = PlAggregate(self)
+        slivers = aggregate.get_slivers(urns)
+        slice = slivers[0]
+        peer = slices.get_peer(slice['hrn'])
+        sfa_peer = slices.get_sfa_peer(slice['hrn'])
+        users = options.get('geni_users', [])
+        persons = slices.verify_persons(None, slice, users, peer, sfa_peer, options=options)
+        slices.handle_peer(None, None, persons, peer)
+        # update sliver allocation states and set them to geni_provisioned
+        sliver_ids = [sliver['sliver_id'] for sliver in slivers]
+        SliverAllocation.set_allocations(sliver_ids, 'geni_provisioned')
+        version_manager = VersionManager()
+        rspec_version = version_manager.get_version(options['geni_rspec_version']) 
+        return self.describe(urns, rspec_version, options=options)
+
+    def delete(self, urns, options={}):
+        # collect sliver ids so we can update sliver allocation states after
+        # we remove the slivers.
+        aggregate = PlAggregate(self)
+        slivers = aggregate.get_slivers(urns)
+        if slivers:
+            slice_id = slivers[0]['slice_id'] 
+            node_ids = []
+            sliver_ids = []
+            for sliver in slivers:
+                node_ids.append(sliver['node_id'])
+                sliver_ids.append(sliver['sliver_id']) 
+
+            # determine if this is a peer slice
+            # xxx I wonder if this would not need to use PlSlices.get_peer instead 
+            # in which case plc.peers could be deprecated as this here
+            # is the only/last call to this last method in plc.peers
+            slice_hrn = PlXrn(auth=self.hrn, slicename=slivers[0]['name']).get_hrn()     
+            peer = peers.get_peer(self, slice_hrn)
+            try:
+                if peer:
+                    self.shell.UnBindObjectFromPeer('slice', slice_id, peer)
+     
+                self.shell.DeleteSliceFromNodes(slice_id, node_ids)
+     
+                # delete sliver allocation states
+                SliverAllocation.delete_allocations(sliver_ids)
+            finally:
+                if peer:
+                    self.shell.BindObjectToPeer('slice', slice_id, peer, slice['peer_slice_id'])
+
+        # prepare return struct
+        geni_slivers = []
+        for sliver in slivers:
+            geni_slivers.append(
+                {'geni_sliver_urn': sliver['sliver_id'],
+                 'geni_allocation_status': 'geni_unallocated',
+                 'geni_expires': datetime_to_string(utcparse(sliver['expires']))})  
+        return geni_slivers
+
+    def renew (self, urns, expiration_time, options={}):
+        aggregate = PlAggregate(self)
+        slivers = aggregate.get_slivers(urns)
+        if not slivers:
+            raise SearchFailed(urns)
+        slice = slivers[0]
         requested_time = utcparse(expiration_time)
         record = {'expires': int(datetime_to_epoch(requested_time))}
         requested_time = utcparse(expiration_time)
         record = {'expires': int(datetime_to_epoch(requested_time))}
-        try:
-            self.shell.UpdateSlice(slice['slice_id'], record)
-            return True
-        except:
-            return False
+        self.shell.UpdateSlice(slice['slice_id'], record)
+        description = self.describe(urns, None, options)
+        return description['geni_slivers']
+            
 
 
-    # remove the 'enabled' tag 
-    def start_slice (self, slice_urn, slice_hrn, creds):
-        slicename = hrn_to_pl_slicename(slice_hrn)
-        slices = self.shell.GetSlices({'name': slicename}, ['slice_id'])
-        if not slices:
-            raise RecordNotFound(slice_hrn)
-        slice_id = slices[0]['slice_id']
-        slice_tags = self.shell.GetSliceTags({'slice_id': slice_id, 'tagname': 'enabled'}, ['slice_tag_id'])
-        # just remove the tag if it exists
-        if slice_tags:
-            self.shell.DeleteSliceTag(slice_tags[0]['slice_tag_id'])
-        return 1
+    def perform_operational_action (self, urns, action, options={}):
+        # MyPLC doesn't support operational actions. Lets pretend like it
+        # supports start, but reject everything else.
+        action = action.lower()
+        if action not in ['geni_start']:
+            raise UnsupportedOperation(action)
+
+        # fault if sliver is not full allocated (operational status is geni_pending_allocation)
+        description = self.describe(urns, None, options)
+        for sliver in description['geni_slivers']:
+            if sliver['geni_operational_status'] == 'geni_pending_allocation':
+                raise UnsupportedOperation(action, "Sliver must be fully allocated (operational status is not geni_pending_allocation)")
+        #
+        # Perform Operational Action Here
+        #
+
+        geni_slivers = self.describe(urns, None, options)['geni_slivers']
+        return geni_slivers
 
     # set the 'enabled' tag to 0
 
     # set the 'enabled' tag to 0
-    def stop_slice (self, slice_urn, slice_hrn, creds):
-        slicename = hrn_to_pl_slicename(slice_hrn)
+    def shutdown (self, xrn, options={}):
+        xrn = PlXrn(xrn=xrn, type='slice')
+        slicename = xrn.pl_slicename()
         slices = self.shell.GetSlices({'name': slicename}, ['slice_id'])
         if not slices:
             raise RecordNotFound(slice_hrn)
         slices = self.shell.GetSlices({'name': slicename}, ['slice_id'])
         if not slices:
             raise RecordNotFound(slice_hrn)
@@ -806,76 +775,3 @@ class PlDriver (Driver):
             tag_id = slice_tags[0]['slice_tag_id']
             self.shell.UpdateSliceTag(tag_id, '0')
         return 1
             tag_id = slice_tags[0]['slice_tag_id']
             self.shell.UpdateSliceTag(tag_id, '0')
         return 1
-    
-    def reset_slice (self, slice_urn, slice_hrn, creds):
-        raise SfaNotImplemented ("reset_slice not available at this interface")
-    
-    # xxx this code is quite old and has not run for ages
-    # it is obviously totally broken and needs a rewrite
-    def get_ticket (self, slice_urn, slice_hrn, creds, rspec_string, options):
-        raise SfaNotImplemented,"PlDriver.get_ticket needs a rewrite"
-# please keep this code for future reference
-#        slices = PlSlices(self)
-#        peer = slices.get_peer(slice_hrn)
-#        sfa_peer = slices.get_sfa_peer(slice_hrn)
-#    
-#        # get the slice record
-#        credential = api.getCredential()
-#        interface = api.registries[api.hrn]
-#        registry = api.server_proxy(interface, credential)
-#        records = registry.Resolve(xrn, credential)
-#    
-#        # make sure we get a local slice record
-#        record = None
-#        for tmp_record in records:
-#            if tmp_record['type'] == 'slice' and \
-#               not tmp_record['peer_authority']:
-#    #Error (E0602, GetTicket): Undefined variable 'SliceRecord'
-#                slice_record = SliceRecord(dict=tmp_record)
-#        if not record:
-#            raise RecordNotFound(slice_hrn)
-#        
-#        # similar to CreateSliver, we must verify that the required records exist
-#        # at this aggregate before we can issue a ticket
-#        # parse rspec
-#        rspec = RSpec(rspec_string)
-#        requested_attributes = rspec.version.get_slice_attributes()
-#    
-#        # ensure site record exists
-#        site = slices.verify_site(slice_hrn, slice_record, peer, sfa_peer)
-#        # ensure slice record exists
-#        slice = slices.verify_slice(slice_hrn, slice_record, peer, sfa_peer)
-#        # ensure person records exists
-#    # xxx users is undefined in this context
-#        persons = slices.verify_persons(slice_hrn, slice, users, peer, sfa_peer)
-#        # ensure slice attributes exists
-#        slices.verify_slice_attributes(slice, requested_attributes)
-#        
-#        # get sliver info
-#        slivers = slices.get_slivers(slice_hrn)
-#    
-#        if not slivers:
-#            raise SliverDoesNotExist(slice_hrn)
-#    
-#        # get initscripts
-#        initscripts = []
-#        data = {
-#            'timestamp': int(time.time()),
-#            'initscripts': initscripts,
-#            'slivers': slivers
-#        }
-#    
-#        # create the ticket
-#        object_gid = record.get_gid_object()
-#        new_ticket = SfaTicket(subject = object_gid.get_subject())
-#        new_ticket.set_gid_caller(api.auth.client_gid)
-#        new_ticket.set_gid_object(object_gid)
-#        new_ticket.set_issuer(key=api.key, subject=self.hrn)
-#        new_ticket.set_pubkey(object_gid.get_pubkey())
-#        new_ticket.set_attributes(data)
-#        new_ticket.set_rspec(rspec)
-#        #new_ticket.set_parent(api.auth.hierarchy.get_auth_ticket(auth_hrn))
-#        new_ticket.encode()
-#        new_ticket.sign()
-#    
-#        return new_ticket.save_to_string(save_parents=True)