示例#1
0
文件: dummydriver.py 项目: tubav/sfa
    def sliver_status(self, slice_urn, slice_hrn):
        # find out where this slice is currently running
        slice_name = hrn_to_dummy_slicename(slice_hrn)

        slice = self.shell.GetSlices({"slice_name": slice_name})
        if len(slices) == 0:
            raise SliverDoesNotExist("%s (used %s as slicename internally)" % (slice_hrn, slicename))

        # report about the local nodes only
        nodes = self.shell.GetNodes({"node_ids": slice["node_ids"]})

        if len(nodes) == 0:
            raise SliverDoesNotExist("You have not allocated any slivers here")

        # get login info
        user = {}
        keys = []
        if slice["user_ids"]:
            users = self.shell.GetUsers({"user_ids": slice["user_ids"]})
            for user in users:
                keys.extend(user["keys"])

            user.update(
                {"urn": slice_urn, "login": slice["slice_name"], "protocol": ["ssh"], "port": ["22"], "keys": keys}
            )

        result = {}
        top_level_status = "unknown"
        if nodes:
            top_level_status = "ready"
        result["geni_urn"] = slice_urn
        result["dummy_login"] = slice["slice_name"]
        result["dummy_expires"] = datetime_to_string(utcparse(slice["expires"]))
        result["geni_expires"] = datetime_to_string(utcparse(slice["expires"]))

        resources = []
        for node in nodes:
            res = {}
            res["dummy_hostname"] = node["hostname"]
            res["geni_expires"] = datetime_to_string(utcparse(slice["expires"]))
            sliver_id = Xrn(slice_urn, type="slice", id=node["node_id"], authority=self.hrn).urn
            res["geni_urn"] = sliver_id
            res["geni_status"] = "ready"
            res["geni_error"] = ""
            res["users"] = [users]

            resources.append(res)

        result["geni_status"] = top_level_status
        result["geni_resources"] = resources
        return result
示例#2
0
    def describe(self, urns, version=None, options={}):
        version_manager = VersionManager()
        version = version_manager.get_version(version)
        rspec_version = version_manager._get_version(version.type,
                                                     version.version,
                                                     'manifest')
        rspec = RSpec(version=rspec_version, user_options=options)

        # get slivers
        geni_slivers = []
        slivers = self.get_slivers(urns, options)
        if slivers:
            rspec_expires = datetime_to_string(utcparse(slivers[0]['expires']))
        else:
            rspec_expires = datetime_to_string(utcparse(time.time()))
        rspec.xml.set('expires', rspec_expires)

        # lookup the sliver allocations
        geni_urn = urns[0]
        sliver_ids = [sliver['sliver_id'] for sliver in slivers]
        constraint = SliverAllocation.sliver_id.in_(sliver_ids)
        sliver_allocations = self.driver.api.dbsession().query(
            SliverAllocation).filter(constraint)
        sliver_allocation_dict = {}
        for sliver_allocation in sliver_allocations:
            geni_urn = sliver_allocation.slice_urn
            sliver_allocation_dict[
                sliver_allocation.sliver_id] = sliver_allocation

        # add slivers
        nodes_dict = {}
        for sliver in slivers:
            nodes_dict[sliver['node_id']] = sliver
        rspec_nodes = []
        for sliver in slivers:
            rspec_node = self.sliver_to_rspec_node(sliver,
                                                   sliver_allocation_dict)
            rspec_nodes.append(rspec_node)
            geni_sliver = self.rspec_node_to_geni_sliver(
                rspec_node, sliver_allocation_dict)
            geni_slivers.append(geni_sliver)
        rspec.version.add_nodes(rspec_nodes)

        return {
            'geni_urn': geni_urn,
            'geni_rspec': rspec.toxml(),
            'geni_slivers': geni_slivers
        }
示例#3
0
    def get_rspec(self, slice_xrn=None, version = None, options={}):

        version_manager = VersionManager()
        version = version_manager.get_version(version)
        if not slice_xrn:
            rspec_version = version_manager._get_version(version.type, version.version, 'ad')
        else:
            rspec_version = version_manager._get_version(version.type, version.version, 'manifest')

        slice, slivers = self.get_slice_and_slivers(slice_xrn)
        rspec = RSpec(version=rspec_version, user_options=options)
        if slice and 'expires' in slice:
            rspec.xml.set('expires',  datetime_to_string(utcparse(slice['expires'])))

        nodes = self.get_nodes(slice_xrn, slice, slivers, options)
        rspec.version.add_nodes(nodes)
        # add sliver defaults
        default_sliver = slivers.get(None, [])
        if default_sliver:
            default_sliver_attribs = default_sliver.get('tags', [])
            for attrib in default_sliver_attribs:
                 logger.info(attrib)
                 rspec.version.add_default_sliver_attribute(attrib['tagname'], attrib['value'])
        
        return rspec.toxml()
示例#4
0
    def sliver_to_rspec_node(self, sliver, sliver_allocations):
        rspec_node = self.node_to_rspec_node(sliver)
        rspec_node['expires'] = datetime_to_string(utcparse(sliver['expires']))
        # add sliver info
        rspec_sliver = Sliver({
            'sliver_id': sliver['urn'],
            'name': sliver['slice_name'],
            'type': 'unigetestbed-vserver',
            'tags': []
        })
        rspec_node['sliver_id'] = rspec_sliver['sliver_id']
        if sliver['urn'] in sliver_allocations:
            rspec_node['client_id'] = sliver_allocations[
                sliver['urn']].client_id
            if sliver_allocations[sliver['urn']].component_id:
                rspec_node['component_id'] = sliver_allocations[
                    sliver['urn']].component_id
        rspec_node['slivers'] = [rspec_sliver]

        # slivers always provide the ssh service
        login = Login({
            'authentication': 'ssh-keys',
            'hostname': sliver['hostname'],
            'port': '22',
            'username': sliver['slice_name'],
            'login': sliver['slice_name']
        })
        return rspec_node
示例#5
0
文件: plslices.py 项目: tubav/sfa
    def verify_slice(self, slice_hrn, slice_record, peer, sfa_peer, options={}):
        slicename = hrn_to_pl_slicename(slice_hrn)
        parts = slicename.split("_")
        login_base = parts[0]
        slices = self.driver.shell.GetSlices([slicename]) 
        if not slices:
            slice = {'name': slicename,
                     'url': slice_record.get('url', slice_hrn), 
                     'description': slice_record.get('description', slice_hrn)}
            # add the slice                          
            slice['slice_id'] = self.driver.shell.AddSlice(slice)
            slice['node_ids'] = []
            slice['person_ids'] = []
            if peer:
                slice['peer_slice_id'] = slice_record.get('slice_id', None) 
            # mark this slice as an sfa peer record
#            if sfa_peer:
#                peer_dict = {'type': 'slice', 'hrn': slice_hrn, 
#                             'peer_authority': sfa_peer, 'pointer': slice['slice_id']}
#                self.registry.register_peer_object(self.credential, peer_dict)
        else:
            slice = slices[0]
            if peer:
                slice['peer_slice_id'] = slice_record.get('slice_id', None)
                # unbind from peer so we can modify if necessary. Will bind back later
                self.driver.shell.UnBindObjectFromPeer('slice', slice['slice_id'], peer['shortname'])
	        #Update existing record (e.g. expires field) it with the latest info.
            if slice_record.get('expires'):
                requested_expires = int(datetime_to_epoch(utcparse(slice_record['expires'])))
                if requested_expires and slice['expires'] != requested_expires:
                    self.driver.shell.UpdateSlice( slice['slice_id'], {'expires' : requested_expires})
       
        return slice
示例#6
0
    def describe(self, urns, version=None, options={}):
        # update nova connection
        tenant_name = OSXrn(xrn=urns[0], type='slice').get_tenant_name()
        self.driver.shell.nova_manager.connect(tenant=tenant_name)
        instances = self.get_instances(urns)
        # lookup the sliver allocations
        sliver_ids = [sliver['sliver_id'] for sliver in slivers]
        constraint = SliverAllocation.sliver_id.in_(sliver_ids)
        sliver_allocations = self.driver.api.dbsession().query(SliverAllocation).filter(constraint)
        sliver_allocation_dict = {}
        for sliver_allocation in sliver_allocations:
            sliver_allocation_dict[sliver_allocation.sliver_id] = sliver_allocation

        geni_slivers = []
        rspec_nodes = []
        for instance in instances:
            rspec_nodes.append(self.instance_to_rspec_node(instance))
            geni_sliver = self.instance_to_geni_sliver(instance, sliver_sllocation_dict)
            geni_slivers.append(geni_sliver)
        version_manager = VersionManager()
        version = version_manager.get_version(version)
        rspec_version = version_manager._get_version(version.type, version.version, 'manifest')
        rspec = RSpec(version=rspec_version, user_options=options)
        rspec.xml.set('expires',  datetime_to_string(utcparse(time.time())))
        rspec.version.add_nodes(rspec_nodes)
        result = {'geni_urn': Xrn(urns[0]).get_urn(),
                  'geni_rspec': rspec.toxml(), 
                  'geni_slivers': geni_slivers}
        
        return result
示例#7
0
    def instance_to_geni_sliver(self, instance, sliver_allocations = {}):
        sliver_hrn = '%s.%s' % (self.driver.hrn, instance.id)
        sliver_id = Xrn(sliver_hrn, type='sliver').urn
 
        # set sliver allocation and operational status
        sliver_allocation = sliver_allocations[sliver_id]
        if sliver_allocation:
            allocation_status = sliver_allocation.allocation_state
            if allocation_status == 'geni_allocated':
                op_status =  'geni_pending_allocation'
            elif allocation_status == 'geni_provisioned':
                state = instance.state.lower()
                if state == 'active':
                    op_status = 'geni_ready'
                elif state == 'building':
                    op_status = 'geni_notready'
                elif state == 'failed':
                    op_status =' geni_failed'
                else:
                    op_status = 'geni_unknown'
            else:
                allocation_status = 'geni_unallocated'    
        # required fields
        geni_sliver = {'geni_sliver_urn': sliver_id, 
                       'geni_expires': None,
                       'geni_allocation_status': allocation_status,
                       'geni_operational_status': op_status,
                       'geni_error': None,
                       'plos_created_at': datetime_to_string(utcparse(instance.created)),
                       'plos_sliver_type': self.shell.nova_manager.flavors.find(id=instance.flavor['id']).name,
                        }

        return geni_sliver
    def delete(self, urns, options={}):
        # collect sliver ids so we can update sliver allocation states after
        # we remove the slivers.
        aggregate = unigetestbedAggregate(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 = unigetestbedXrn(auth=self.hrn, slicename=slivers[0]['slice_name']).get_hrn()
            try:
                self.shell.DeleteSliceFromNodes({'slice_id': slice_id, 'node_ids': node_ids})
                # delete sliver allocation states
                dbsession=self.api.dbsession()
                SliverAllocation.delete_allocations(sliver_ids,dbsession)
            finally:
                pass

        # 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 verify_slice(self, slice_hrn, slice_record, expiration, options={}):
        slicename = hrn_to_unigetestbed_slicename(slice_hrn)
        parts = slicename.split("_")
        login_base = parts[0]
        slices = self.driver.shell.GetSlices({'slice_name': slicename})
        if not slices:
            slice = {'slice_name': slicename}
            # add the slice
            slice['slice_id'] = self.driver.shell.AddSlice(slice)
            slice['node_ids'] = []
            slice['user_ids'] = []
        else:
            slice = slices[0]
            if slice_record and slice_record.get('expires'):
                requested_expires = int(
                    datetime_to_epoch(utcparse(slice_record['expires'])))
                if requested_expires and slice['expires'] != requested_expires:
                    self.driver.shell.UpdateSlice({
                        'slice_id': slice['slice_id'],
                        'fields': {
                            'expires': expiration
                        }
                    })

        return slice
示例#10
0
    def sliver_to_rspec_node(self, sliver, sites, interfaces, node_tags, \
                             pl_initscripts, sliver_allocations):
        # get the granularity in second for the reservation system
        grain = self.driver.shell.GetLeaseGranularity()
        rspec_node = self.node_to_rspec_node(sliver, sites, interfaces, node_tags, pl_initscripts, grain)
        # xxx how to retrieve site['login_base']
        rspec_node['expires'] = datetime_to_string(utcparse(sliver['expires']))
        # remove interfaces from manifest
        rspec_node['interfaces'] = []
        # add sliver info
        rspec_sliver = Sliver({'sliver_id': sliver['urn'],
                         'name': sliver['name'],
                         'type': 'plab-vserver',
                         'tags': []})
        rspec_node['sliver_id'] = rspec_sliver['sliver_id']
        if sliver['urn'] in sliver_allocations:
            rspec_node['client_id'] = sliver_allocations[sliver['urn']].client_id
            if sliver_allocations[sliver['urn']].component_id:
                rspec_node['component_id'] = sliver_allocations[sliver['urn']].component_id
        rspec_node['slivers'] = [rspec_sliver]

        # slivers always provide the ssh service
        login = Login({'authentication': 'ssh-keys', 
                       'hostname': sliver['hostname'], 
                       'port':'22', 
                       'username': sliver['name'],
                       'login': sliver['name']
                      })
        service = ServicesElement({'login': login,
                            'services_user': sliver['services_user']})
        rspec_node['services'] = [service]    
        return rspec_node      
示例#11
0
    def describe(self, urns, version=None, options=None):
        if options is None: options={}
        version_manager = VersionManager()
        version = version_manager.get_version(version)
        rspec_version = version_manager._get_version(version.type, version.version, 'manifest')
        rspec = RSpec(version=rspec_version, user_options=options)

        # Update connection for the current user
        xrn = Xrn(urns[0], type='slice')
        user_name = xrn.get_authority_hrn() + '.' + xrn.leaf.split('-')[0]
        tenant_name = OSXrn(xrn=urns[0], type='slice').get_hrn()
        self.driver.shell.compute_manager.connect(username=user_name, tenant=tenant_name, password=user_name)

        # For delay to collect instance info 
        time.sleep(3)
        # Get instances from the Openstack
        instances = self.get_instances(xrn)

        # Add sliver(s) from instance(s)
        geni_slivers = []
        rspec.xml.set( 'expires',  datetime_to_string(utcparse(time.time())) )
        rspec_nodes = []
        for instance in instances:
            rspec_nodes.append(self.instance_to_rspec_node(instance))
            geni_sliver = self.instance_to_geni_sliver(instance)
            geni_slivers.append(geni_sliver)
        rspec.version.add_nodes(rspec_nodes)

        result = { 'geni_urn': xrn.get_urn(),
                   'geni_rspec': rspec.toxml(), 
                   'geni_slivers': geni_slivers }
        return result
示例#12
0
    def GetCredential(self, api, xrn, type, caller_xrn=None):
        # convert xrn to hrn     
        if type:
            hrn = urn_to_hrn(xrn)[0]
        else:
            hrn, type = urn_to_hrn(xrn)

        # Is this a root or sub authority
        auth_hrn = api.auth.get_authority(hrn)
        if not auth_hrn or hrn == api.config.SFA_INTERFACE_HRN:
            auth_hrn = hrn
        auth_info = api.auth.get_auth_info(auth_hrn)
        # get record info
        record=dbsession.query(RegRecord).filter_by(type=type,hrn=hrn).first()
        if not record:
            raise RecordNotFound("hrn=%s, type=%s"%(hrn,type))

        # get the callers gid
        # if caller_xrn is not specified assume the caller is the record
        # object itself.
        if not caller_xrn:
            caller_hrn = hrn
            caller_gid = record.get_gid_object()
        else:
            caller_hrn, caller_type = urn_to_hrn(caller_xrn)
            if caller_type:
                caller_record = dbsession.query(RegRecord).filter_by(hrn=caller_hrn,type=caller_type).first()
            else:
                caller_record = dbsession.query(RegRecord).filter_by(hrn=caller_hrn).first()
            if not caller_record:
                raise RecordNotFound("Unable to associated caller (hrn=%s, type=%s) with credential for (hrn: %s, type: %s)"%(caller_hrn, caller_type, hrn, type))
            caller_gid = GID(string=caller_record.gid)

        object_hrn = record.get_gid_object().get_hrn()
        # call the builtin authorization/credential generation engine
        rights = api.auth.determine_user_rights(caller_hrn, record)
        # make sure caller has rights to this object
        if rights.is_empty():
            raise PermissionError("%s has no rights to %s (%s)" % \
                                  (caller_hrn, object_hrn, xrn))
        object_gid = GID(string=record.gid)
        new_cred = Credential(subject = object_gid.get_subject())
        new_cred.set_gid_caller(caller_gid)
        new_cred.set_gid_object(object_gid)
        new_cred.set_issuer_keys(auth_info.get_privkey_filename(), auth_info.get_gid_filename())
        #new_cred.set_pubkey(object_gid.get_pubkey())
        new_cred.set_privileges(rights)
        new_cred.get_privileges().delegate_all_privileges(True)
        if hasattr(record,'expires'):
            date = utcparse(record.expires)
            expires = datetime_to_epoch(date)
            new_cred.set_expiration(int(expires))
        auth_kind = "authority,ma,sa"
        # Parent not necessary, verify with certs
        #new_cred.set_parent(api.auth.hierarchy.get_auth_cred(auth_hrn, kind=auth_kind))
        new_cred.encode()
        new_cred.sign()

        return new_cred.save_to_string(save_parents=True)
示例#13
0
    def GetCredential(self, api, xrn, type, caller_xrn=None):
        # convert xrn to hrn     
        if type:
            hrn = urn_to_hrn(xrn)[0]
        else:
            hrn, type = urn_to_hrn(xrn)

        # Is this a root or sub authority
        auth_hrn = api.auth.get_authority(hrn)
        if not auth_hrn or hrn == api.config.SFA_INTERFACE_HRN:
            auth_hrn = hrn
        auth_info = api.auth.get_auth_info(auth_hrn)
        # get record info
        record=dbsession.query(RegRecord).filter_by(type=type,hrn=hrn).first()
        if not record:
            raise RecordNotFound("hrn=%s, type=%s"%(hrn,type))

        # get the callers gid
        # if caller_xrn is not specified assume the caller is the record
        # object itself.
        if not caller_xrn:
            caller_hrn = hrn
            caller_gid = record.get_gid_object()
        else:
            caller_hrn, caller_type = urn_to_hrn(caller_xrn)
            if caller_type:
                caller_record = dbsession.query(RegRecord).filter_by(hrn=caller_hrn,type=caller_type).first()
            else:
                caller_record = dbsession.query(RegRecord).filter_by(hrn=caller_hrn).first()
            if not caller_record:
                raise RecordNotFound("Unable to associated caller (hrn=%s, type=%s) with credential for (hrn: %s, type: %s)"%(caller_hrn, caller_type, hrn, type))
            caller_gid = GID(string=caller_record.gid)i

        object_hrn = record.get_gid_object().get_hrn()
        # call the builtin authorization/credential generation engine
        rights = api.auth.determine_user_rights(caller_hrn, record)
        # make sure caller has rights to this object
        if rights.is_empty():
            raise PermissionError("%s has no rights to %s (%s)" % \
                                  (caller_hrn, object_hrn, xrn))
        object_gid = GID(string=record.gid)
        new_cred = Credential(subject = object_gid.get_subject())
        new_cred.set_gid_caller(caller_gid)
        new_cred.set_gid_object(object_gid)
        new_cred.set_issuer_keys(auth_info.get_privkey_filename(), auth_info.get_gid_filename())
        #new_cred.set_pubkey(object_gid.get_pubkey())
        new_cred.set_privileges(rights)
        new_cred.get_privileges().delegate_all_privileges(True)
        if hasattr(record,'expires'):
            date = utcparse(record.expires)
            expires = datetime_to_epoch(date)
            new_cred.set_expiration(int(expires))
        auth_kind = "authority,ma,sa"
        # Parent not necessary, verify with certs
        #new_cred.set_parent(api.auth.hierarchy.get_auth_cred(auth_hrn, kind=auth_kind))
        new_cred.encode()
        new_cred.sign()

        return new_cred.save_to_string(save_parents=True)
示例#14
0
    def verify_slice(self,
                     slice_hrn,
                     slice_record,
                     sfa_peer,
                     expiration,
                     options={}):
        #top_auth_hrn = top_auth(slice_hrn)
        #site_hrn = '.'.join(slice_hrn.split('.')[:-1])
        #slice_part = slice_hrn.split('.')[-1]
        #if top_auth_hrn == self.driver.hrn:
        #    login_base = slice_hrn.split('.')[-2][:12]
        #else:
        #    login_base = hash_loginbase(site_hrn)
        #slice_name = '_'.join([login_base, slice_part])
        plxrn = PlXrn(xrn=slice_hrn)
        slice_hrn = plxrn.get_hrn()
        type = plxrn.get_type()
        site_hrn = plxrn.get_authority_hrn()
        authority_name = plxrn.pl_authname()
        slicename = plxrn.pl_slicename()
        login_base = plxrn.pl_login_base()

        slices = self.driver.shell.GetSlices({'peer_id': None},
                                             ['slice_id', 'name', 'hrn'])
        # Filter slices by HRN
        slice_exists = [slice for slice in slices if slice['hrn'] == slice_hrn]
        expires = int(datetime_to_epoch(utcparse(expiration)))
        if not slice_exists:
            if slice_record:
                url = slice_record.get('url', slice_hrn)
                description = slice_record.get('description', slice_hrn)
            else:
                url = slice_hrn
                description = slice_hrn
            slice = {
                'name': slice_name,
                'url': url,
                'description': description
            }
            # add the slice
            slice['slice_id'] = self.driver.shell.AddSlice(slice)
            # set the slice HRN
            self.driver.shell.SetSliceHrn(int(slice['slice_id']), slice_hrn)
            # Tag this as created through SFA
            self.driver.shell.SetSliceSfaCreated(int(slice['slice_id']),
                                                 'True')
            # set the expiration
            self.driver.shell.UpdateSlice(int(slice['slice_id']),
                                          {'expires': expires})

        else:
            slice = slice_exists[0]
            #Update expiration if necessary
            if slice.get('expires', None) != expires:
                self.driver.shell.UpdateSlice(int(slice['slice_id']),
                                              {'expires': expires})

        return self.driver.shell.GetSlices(int(slice['slice_id']))[0]
示例#15
0
 def set_expiration(self, expiration):
     if isinstance(expiration, (int, float)):
         self.expiration = datetime.datetime.fromtimestamp(expiration)
     elif isinstance(expiration, datetime.datetime):
         self.expiration = expiration
     elif isinstance(expiration, StringTypes):
         self.expiration = utcparse(expiration)
     else:
         logger.error("unexpected input type in Credential.set_expiration")
示例#16
0
 def set_expiration(self, expiration):
     if isinstance(expiration, (int, float)):
         self.expiration = datetime.datetime.fromtimestamp(expiration)
     elif isinstance(expiration, datetime.datetime):
         self.expiration = expiration
     elif isinstance(expiration, StringTypes):
         self.expiration = utcparse(expiration)
     else:
         logger.error("unexpected input type in Credential.set_expiration")
示例#17
0
 def date_repr (self,fields):
     if not isinstance(fields,list): fields=[fields]
     for field in fields:
         value=getattr(self,field,None)
         if isinstance (value,datetime):
             return datetime_to_string (value)
         elif isinstance (value,(int,float)):
             return datetime_to_string(utcparse(value))
     # fallback
     return "** undef_datetime **"
示例#18
0
文件: record.py 项目: gnogueras/sfa
 def date_repr (self,fields):
     if not isinstance(fields,list): fields=[fields]
     for field in fields:
         value=getattr(self,field,None)
         if isinstance (value,datetime):
             return datetime_to_string (value)
         elif isinstance (value,(int,float)):
             return datetime_to_string(utcparse(value))
     # fallback
     return "** undef_datetime **"
示例#19
0
 def renew (self, urns, expiration_time, options={}):
     aggregate = unigetestbedAggregate(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))}
     self.shell.UpdateSlice({'slice_id': slice['slice_id'], 'fileds': record})
     description = self.describe(urns, 'GENI 3', options)
     return description['geni_slivers']
示例#20
0
文件: pldriver.py 项目: gnogueras/sfa
 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))}
     self.shell.UpdateSlice(slice['slice_id'], record)
     description = self.describe(urns, 'GENI 3', options)
     return description['geni_slivers']
示例#21
0
    def describe(self, urns, version=None, options=None):
        if options is None: options={}
        version_manager = VersionManager()
        version = version_manager.get_version(version)
        rspec_version = version_manager._get_version(version.type, version.version, 'manifest')
        rspec = RSpec(version=rspec_version, user_options=options)

        # get slivers
        geni_slivers = []
        slivers = self.get_slivers(urns, options)
        if slivers:
            rspec_expires = datetime_to_string(utcparse(slivers[0]['expires']))
        else:
            rspec_expires = datetime_to_string(utcparse(time.time()))
        rspec.xml.set('expires',  rspec_expires)

        # lookup the sliver allocations
        geni_urn = urns[0]
        sliver_ids = [sliver['sliver_id'] for sliver in slivers]
        constraint = SliverAllocation.sliver_id.in_(sliver_ids)
        sliver_allocations = self.driver.api.dbsession().query(SliverAllocation).filter(constraint)
        sliver_allocation_dict = {}
        for sliver_allocation in sliver_allocations:
            geni_urn = sliver_allocation.slice_urn
            sliver_allocation_dict[sliver_allocation.sliver_id] = sliver_allocation

        # add slivers
        nodes_dict = {}
        for sliver in slivers:
            nodes_dict[sliver['node_id']] = sliver
        rspec_nodes = []
        for sliver in slivers:
            rspec_node = self.sliver_to_rspec_node(sliver, sliver_allocation_dict)
            rspec_nodes.append(rspec_node)
            geni_sliver = self.rspec_node_to_geni_sliver(rspec_node, sliver_allocation_dict)
            geni_slivers.append(geni_sliver)
        rspec.version.add_nodes(rspec_nodes)

        return {'geni_urn': geni_urn,
                'geni_rspec': rspec.toxml(),
                'geni_slivers': geni_slivers}
示例#22
0
文件: pldriver.py 项目: tubav/sfa
 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]
     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
示例#23
0
    def Renew(self, api, xrns, creds, expiration_time, options):
        call_id = options.get('call_id')
        if Callids().already_handled(call_id): return True

        # extend as long as possible
        if options.get('geni_extend_alap'):
            now = datetime.datetime.now()
            requested = utcparse(expiration_time)
            max = adjust_datetime(now, days=int(api.config.SFA_MAX_SLICE_RENEW))
            if requested > max:
                expiration_time = max
        options['creds']=creds
        return api.driver.renew(xrns, expiration_time, options)
示例#24
0
文件: dummydriver.py 项目: tubav/sfa
 def renew_sliver(self, slice_urn, slice_hrn, creds, expiration_time, options):
     slicename = hrn_to_dummy_slicename(slice_hrn)
     slices = self.shell.GetSlices({"slice_name": slicename})
     if not slices:
         raise RecordNotFound(slice_hrn)
     slice = slices[0]
     requested_time = utcparse(expiration_time)
     record = {"expires": int(datetime_to_epoch(requested_time))}
     try:
         self.shell.UpdateSlice({"slice_id": slice["slice_id"], "fields": record})
         return True
     except:
         return False
示例#25
0
    def sliver_to_rspec_node(self, sliver, sliver_allocations):
        """Used by describe to format node information into a rspec compliant
        structure.

        Creates a node rspec compliant structure by calling node_to_rspec_node.
        Adds slivers, if any, to rspec node structure. Returns the updated
        rspec node struct.

        :param sliver: sliver dictionary. Contains keys: urn, slice_id, hostname
            and slice_name.
        :type sliver: dictionary
        :param sliver_allocations: dictionary of slivers
        :type sliver_allocations: dict

        :returns: Node dictionary with all necessary data.

        .. seealso:: node_to_rspec_node
        """
        rspec_node = self.node_to_rspec_node(sliver)
        rspec_node['expires'] = datetime_to_string(utcparse(sliver['expires']))
        # add sliver info
        logger.debug("CORTEXLABAGGREGATE api \t  sliver_to_rspec_node sliver \
                        %s \r\nsliver_allocations %s" %
                     (sliver, sliver_allocations))
        rspec_sliver = Sliver({
            'sliver_id': sliver['urn'],
            'name': sliver['slice_id'],
            'type': 'iotlab-exclusive',
            'tags': []
        })
        rspec_node['sliver_id'] = rspec_sliver['sliver_id']

        if sliver['urn'] in sliver_allocations:
            rspec_node['client_id'] = sliver_allocations[
                sliver['urn']].client_id
            if sliver_allocations[sliver['urn']].component_id:
                rspec_node['component_id'] = sliver_allocations[
                    sliver['urn']].component_id
        rspec_node['slivers'] = [rspec_sliver]

        # slivers always provide the ssh service
        login = Login({
            'authentication': 'ssh-keys',
            'hostname': sliver['hostname'],
            'port': '22',
            'username': sliver['slice_name'],
            'login': sliver['slice_name']
        })
        return rspec_node
示例#26
0
    def renew_sliver(self, slice_urn, slice_hrn, creds, expiration_time,
                     options):
        slicename = hrn_to_nitos_slicename(slice_hrn)
        slices = self.shell.GetSlices({'slicename': slicename}, ['slice_id'])
        if not slices:
            raise RecordNotFound(slice_hrn)
        slice = slices[0]
        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
示例#27
0
def RenewSliver(api, xrn, creds, expiration_time, call_id):
    if Callids().already_handled(call_id): return True
    (hrn, type) = urn_to_hrn(xrn)
    slicename = hrn_to_pl_slicename(hrn)
    slices = api.plshell.GetSlices(api.plauth, {'name': slicename}, ['slice_id'])
    if not slices:
        raise RecordNotFound(hrn)
    slice = slices[0]
    requested_time = utcparse(expiration_time)
    record = {'expires': int(time.mktime(requested_time.timetuple()))}
    try:
        api.plshell.UpdateSlice(api.plauth, slice['slice_id'], record)
        return True
    except:
        return False
示例#28
0
文件: nova_driver.py 项目: tubav/sfa
    def sliver_status (self, slice_urn, slice_hrn):
        # update nova connection
        tenant_name = OSXrn(xrn=slice_hrn, type='slice').get_tenant_name()
        self.shell.nova_manager.connect(tenant=tenant_name)

        # find out where this slice is currently running
        project_name = hrn_to_os_slicename(slice_hrn)
        instances = self.shell.nova_manager.servers.findall(name=project_name)
        if len(instances) == 0:
            raise SliverDoesNotExist("You have not allocated any slivers here") 
        
        result = {}
        top_level_status = 'ready'
        result['geni_urn'] = slice_urn
        result['plos_login'] = '******'
        # do we need real dates here? 
        result['plos_expires'] = None
        result['geni_expires'] = None
        
        resources = []
        for instance in instances:
            res = {}
            # instances are accessed by ip, not hostname. We need to report the ip
            # somewhere so users know where to ssh to.     
            res['geni_expires'] = None
            #res['plos_hostname'] = instance.hostname
            res['plos_created_at'] = datetime_to_string(utcparse(instance.created))    
            res['plos_boot_state'] = instance.status
            res['plos_sliver_type'] = self.shell.nova_manager.flavors.find(id=instance.flavor['id']).name 
            res['geni_urn'] =  Xrn(slice_urn, type='slice', id=instance.id).get_urn()

            if instance.status.lower() == 'active':
                res['boot_state'] = 'ready'
                res['geni_status'] = 'ready'
            elif instance.status.lower() == 'error':
                res['boot_state'] = 'failed'
                res['geni_status'] = 'failed'
                top_level_status = 'failed'
            else:
                res['boot_state'] = 'notready'  
                res['geni_status'] = 'notready'
                top_level_status = 'notready'
            resources.append(res)
            
        result['geni_status'] = top_level_status
        result['geni_resources'] = resources
        return result
示例#29
0
文件: RenewSliver.py 项目: tubav/sfa
    def call(self, slice_xrn, creds, expiration_time, options):

        (hrn, type) = urn_to_hrn(slice_xrn)

        self.api.logger.info("interface: %s\ttarget-hrn: %s\tcaller-creds: %s\tmethod-name: %s"%(self.api.interface, hrn, creds, self.name))

        # Find the valid credentials
        valid_creds = self.api.auth.checkCredentials(creds, 'renewsliver', hrn)

        # Validate that the time does not go beyond the credential's expiration time
        requested_time = utcparse(expiration_time)
        max_renew_days = int(self.api.config.SFA_MAX_SLICE_RENEW)
        if requested_time > Credential(string=valid_creds[0]).get_expiration():
            raise InsufficientRights('Renewsliver: Credential expires before requested expiration time')
        if requested_time > datetime.datetime.utcnow() + datetime.timedelta(days=max_renew_days):
            raise Exception('Cannot renew > %s days from now' % max_renew_days)
        return self.api.manager.RenewSliver(self.api, slice_xrn, valid_creds, expiration_time, options)
示例#30
0
    def sliver_to_rspec_node(self, sliver, sliver_allocations):
        """Used by describe to format node information into a rspec compliant
        structure.

        Creates a node rspec compliant structure by calling node_to_rspec_node.
        Adds slivers, if any, to rspec node structure. Returns the updated
        rspec node struct.

        :param sliver: sliver dictionary. Contains keys: urn, slice_id, hostname
            and slice_name.
        :type sliver: dictionary
        :param sliver_allocations: dictionary of slivers
        :type sliver_allocations: dict

        :returns: Node dictionary with all necessary data.

        .. seealso:: node_to_rspec_node
        """
        rspec_node = self.node_to_rspec_node(sliver)
        rspec_node['expires'] = datetime_to_string(utcparse(sliver['expires']))
        # add sliver info
        logger.debug("IOTLABAGGREGATE api \t  sliver_to_rspec_node sliver \
                        %s \r\nsliver_allocations %s" % (sliver,
                            sliver_allocations))
        rspec_sliver = Sliver({'sliver_id': sliver['urn'],
                         'name': sliver['slice_id'],
                         'type': 'iotlab-exclusive',
                         'tags': []})
        rspec_node['sliver_id'] = rspec_sliver['sliver_id']

        if sliver['urn'] in sliver_allocations:
            rspec_node['client_id'] = sliver_allocations[
                                                    sliver['urn']].client_id
            if sliver_allocations[sliver['urn']].component_id:
                rspec_node['component_id'] = sliver_allocations[
                                                    sliver['urn']].component_id
        rspec_node['slivers'] = [rspec_sliver]

        # slivers always provide the ssh service
        login = Login({'authentication': 'ssh-keys',
                       'hostname': sliver['hostname'],
                       'port':'22',
                       'username': sliver['slice_name'],
                       'login': sliver['slice_name']
                      })
        return rspec_node
示例#31
0
文件: pldriver.py 项目: gnogueras/sfa
    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']
            slice_name = slivers[0]['name']
            node_ids = []
            sliver_ids = []
            for sliver in slivers:
                node_ids.append(sliver['node_id'])
                sliver_ids.append(sliver['sliver_id'])

            # leases
            leases = self.shell.GetLeases({
                'name': slice_name,
                'node_id': node_ids
            })
            leases_ids = [lease['lease_id'] for lease in leases]

            slice_hrn = self.shell.GetSliceHrn(int(slice_id))
            try:
                self.shell.DeleteSliceFromNodes(slice_id, node_ids)
                if len(leases_ids) > 0:
                    self.shell.DeleteLeases(leases_ids)

                # delete sliver allocation states
                dbsession = self.api.dbsession()
                SliverAllocation.delete_allocations(sliver_ids, dbsession)
            finally:
                pass

        # 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
示例#32
0
    def verify_slice(self, slice_hrn, slice_record, sfa_peer, expiration, options=None):
        if options is None: options={}
        top_auth_hrn = top_auth(slice_hrn)
        site_hrn = '.'.join(slice_hrn.split('.')[:-1])
        slice_part = slice_hrn.split('.')[-1]
        if top_auth_hrn == self.driver.hrn:
            login_base = slice_hrn.split('.')[-2][:12]
        else:
            login_base = hash_loginbase(site_hrn)
        slice_name = '_'.join([login_base, slice_part])

        expires = int(datetime_to_epoch(utcparse(expiration)))
        # Filter slices by HRN
        slices = self.driver.shell.GetSlices({'peer_id': None, 'hrn':slice_hrn},
                                             ['slice_id','name','hrn','expires'])
        
        if slices:
            slice = slices[0]
            slice_id = slice['slice_id']
            #Update expiration if necessary
            if slice.get('expires', None) != expires:
                self.driver.shell.UpdateSlice( slice_id, {'expires' : expires})
        else:
            if slice_record:
                url = slice_record.get('url', slice_hrn)
                description = slice_record.get('description', slice_hrn)
            else:
                url = slice_hrn
                description = slice_hrn
            slice = {'name': slice_name,
                     'url': url,
                     'description': description,
                     'hrn': slice_hrn,
                     'sfa_created': 'True',
                     #'expires': expires,
            }
            # add the slice
            slice_id = self.driver.shell.AddSlice(slice)
            # plcapi tends to mess with the incoming hrn so let's make sure
            self.driver.shell.SetSliceHrn (slice_id, slice_hrn)
            # cannot be set with AddSlice
            # set the expiration
            self.driver.shell.UpdateSlice(slice_id, {'expires': expires})

        return self.driver.shell.GetSlices(slice_id)[0]
示例#33
0
文件: dummyslices.py 项目: aquila/sfa
 def verify_slice(self, slice_hrn, slice_record, expiration, options={}):
     slicename = hrn_to_dummy_slicename(slice_hrn)
     parts = slicename.split("_")
     login_base = parts[0]
     slices = self.driver.shell.GetSlices({'slice_name': slicename}) 
     if not slices:
         slice = {'slice_name': slicename}
         # add the slice                          
         slice['slice_id'] = self.driver.shell.AddSlice(slice)
         slice['node_ids'] = []
         slice['user_ids'] = []
     else:
         slice = slices[0]
         if slice_record and slice_record.get('expires'):
             requested_expires = int(datetime_to_epoch(utcparse(slice_record['expires'])))
             if requested_expires and slice['expires'] != requested_expires:
                 self.driver.shell.UpdateSlice( {'slice_id': slice['slice_id'], 'fields':{'expires' : expiration}})
    
     return slice
示例#34
0
文件: pldriver.py 项目: gnogueras/sfa
    def sfa_fields_to_pl_fields(self, type, hrn, sfa_record):

        pl_record = {}

        if type == "slice":
            pl_record["name"] = hrn_to_pl_slicename(hrn)
            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:
                date = utcparse(sfa_record['expires'])
                expires = datetime_to_epoch(date)
                pl_record["expires"] = expires

        elif type == "node":
            if not "hostname" in pl_record:
                # fetch from sfa_record
                if "hostname" not in sfa_record:
                    raise MissingSfaInfo("hostname")
                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"] = PlXrn(xrn=hrn,
                                            type='authority').pl_login_base()
            if "name" not in sfa_record:
                pl_record["name"] = hrn
            if "abbreviated_name" not in sfa_record:
                pl_record["abbreviated_name"] = hrn
            if "enabled" not in sfa_record:
                pl_record["enabled"] = True
            if "is_public" not in sfa_record:
                pl_record["is_public"] = True

        return pl_record
示例#35
0
文件: Renew.py 项目: gnogueras/sfa
    def call(self, urns, creds, expiration_time, options):

        self.api.logger.info("interface: %s\ttarget-hrn: %s\tcaller-creds: %s\tmethod-name: %s"%(self.api.interface, urns, creds, self.name))

        (speaking_for, _) = urn_to_hrn(options.get('geni_speaking_for'))
    
        # Find the valid credentials
        valid_creds = self.api.auth.checkCredentials(creds, 'renewsliver', urns,
                      check_sliver_callback = self.api.driver.check_sliver_credentials,
                      speaking_for_hrn=speaking_for)

        # Validate that the time does not go beyond the credential's expiration time
        requested_time = utcparse(expiration_time)
        max_renew_days = int(self.api.config.SFA_MAX_SLICE_RENEW)
        if requested_time > Credential(cred=valid_creds[0]).get_expiration():
            raise InsufficientRights('Renewsliver: Credential expires before requested expiration time')
        if requested_time > datetime.datetime.utcnow() + datetime.timedelta(days=max_renew_days):
            raise Exception('Cannot renew > %s days from now' % max_renew_days)
        return self.api.manager.Renew(self.api, urns, creds, expiration_time, options)
示例#36
0
文件: pldriver.py 项目: tubav/sfa
    def sfa_fields_to_pl_fields(self, type, hrn, sfa_record):

        pl_record = {}
 
        if type == "slice":
            pl_record["name"] = hrn_to_pl_slicename(hrn)
            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:
                date = utcparse(sfa_record['expires'])
                expires = datetime_to_epoch(date)
                pl_record["expires"] = expires

        elif type == "node":
            if not "hostname" in pl_record:
                # fetch from sfa_record
                if "hostname" not in sfa_record:
                    raise MissingSfaInfo("hostname")
                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"] = PlXrn(xrn=hrn,type='authority').pl_login_base()
            if "name" not in sfa_record:
                pl_record["name"] = hrn
            if "abbreviated_name" not in sfa_record:
                pl_record["abbreviated_name"] = hrn
            if "enabled" not in sfa_record:
                pl_record["enabled"] = True
            if "is_public" not in sfa_record:
                pl_record["is_public"] = True

        return pl_record
示例#37
0
    def delete(self, urns, options={}):
        # collect sliver ids so we can update sliver allocation states after
        # we remove the slivers.
        aggregate = DummyAggregate(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 = DummyXrn(auth=self.hrn,
                                 slicename=slivers[0]['slice_name']).get_hrn()
            try:
                self.shell.DeleteSliceFromNodes({
                    'slice_id': slice_id,
                    'node_ids': node_ids
                })
                # delete sliver allocation states
                dbsession = self.api.dbsession()
                SliverAllocation.delete_allocations(sliver_ids, dbsession)
            finally:
                pass

        # 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
示例#38
0
    def get_rspec(self, slice_xrn=None, version=None, options={}):

        version_manager = VersionManager()
        version = version_manager.get_version(version)

        if not slice_xrn:
            rspec_version = version_manager._get_version(
                version.type, version.version, 'ad')
        else:
            rspec_version = version_manager._get_version(
                version.type, version.version, 'manifest')

        slice, slivers = self.get_slice_and_slivers(slice_xrn)

        rspec = RSpec(version=rspec_version, user_options=options)

        if slice and 'expires' in slice:
            rspec.xml.set('expires',
                          datetime_to_string(utcparse(slice['expires'])))

        if not options.get('list_leases') or options.get(
                'list_leases') and options['list_leases'] != 'leases':
            nodes = self.get_nodes(slice_xrn, slice, slivers, options)
            rspec.version.add_nodes(nodes)
            # add sliver defaults
            default_sliver = slivers.get(None, [])
            if default_sliver:
                default_sliver_attribs = default_sliver.get('tags', [])
                for attrib in default_sliver_attribs:
                    logger.info(attrib)
                    rspec.version.add_default_sliver_attribute(
                        attrib['tagname'], attrib['value'])
            # add wifi channels
            channels = self.get_channels(slice, options)
            rspec.version.add_channels(channels)

        if not options.get('list_leases') or options.get(
                'list_leases') and options['list_leases'] != 'resources':
            leases_channels = self.get_leases_and_channels(slice, slice_xrn)
            rspec.version.add_leases(leases_channels)

        return rspec.toxml()
示例#39
0
    def sliver_to_rspec_node(self, sliver, sites, interfaces, node_tags, \
                             pl_initscripts, sliver_allocations):
        # get the granularity in second for the reservation system
        grain = self.driver.shell.GetLeaseGranularity()
        rspec_node = self.node_to_rspec_node(sliver, sites, interfaces,
                                             node_tags, pl_initscripts, grain)
        # xxx how to retrieve site['login_base']
        rspec_node['expires'] = datetime_to_string(utcparse(sliver['expires']))
        # remove interfaces from manifest
        rspec_node['interfaces'] = []
        # add sliver info
        rspec_sliver = Sliver({
            'sliver_id': sliver['urn'],
            'name': sliver['name'],
            'type': 'plab-vserver',
            'tags': []
        })
        rspec_node['sliver_id'] = rspec_sliver['sliver_id']
        if sliver['urn'] in sliver_allocations:
            rspec_node['client_id'] = sliver_allocations[
                sliver['urn']].client_id
            if sliver_allocations[sliver['urn']].component_id:
                rspec_node['component_id'] = sliver_allocations[
                    sliver['urn']].component_id
        rspec_node['slivers'] = [rspec_sliver]

        # slivers always provide the ssh service
        login = Login({
            'authentication': 'ssh-keys',
            'hostname': sliver['hostname'],
            'port': '22',
            'username': sliver['name'],
            'login': sliver['name']
        })
        service = ServicesElement({
            'login': login,
            'services_user': sliver['services_user']
        })
        rspec_node['services'] = [service]
        return rspec_node
示例#40
0
    def delete(self, urns, options=None):
        if options is None: 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'] 
            slice_name = slivers[0]['name']
            node_ids = []
            sliver_ids = []
            for sliver in slivers:
                node_ids.append(sliver['node_id'])
                sliver_ids.append(sliver['sliver_id']) 

            # leases
            leases = self.shell.GetLeases({'name': slice_name, 'node_id': node_ids})
            leases_ids = [lease['lease_id'] for lease in leases ]

            slice_hrn = self.shell.GetSliceHrn(int(slice_id))
            try:
                self.shell.DeleteSliceFromNodes(slice_id, node_ids)
                if len(leases_ids) > 0:
                    self.shell.DeleteLeases(leases_ids)
     
                # delete sliver allocation states
                dbsession=self.api.dbsession()
                SliverAllocation.delete_allocations(sliver_ids,dbsession)
            finally:
                pass

        # 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
示例#41
0
    def sliver_to_rspec_node(self, sliver, sliver_allocations):
        rspec_node = self.node_to_rspec_node(sliver)
        rspec_node['expires'] = datetime_to_string(utcparse(sliver['expires']))
        # add sliver info
        rspec_sliver = Sliver({'sliver_id': sliver['urn'],
                         'name': sliver['slice_name'],
                         'type': 'dummy-vserver',
                         'tags': []})
        rspec_node['sliver_id'] = rspec_sliver['sliver_id']
        if sliver['urn'] in sliver_allocations:
            rspec_node['client_id'] = sliver_allocations[sliver['urn']].client_id
            if sliver_allocations[sliver['urn']].component_id:
                rspec_node['component_id'] = sliver_allocations[sliver['urn']].component_id
        rspec_node['slivers'] = [rspec_sliver]

        # slivers always provide the ssh service
        login = Login({'authentication': 'ssh-keys',
                       'hostname': sliver['hostname'],
                       'port':'22',
                       'username': sliver['slice_name'],
                       'login': sliver['slice_name']
                      })
        return rspec_node
示例#42
0
    def get_rspec(self, slice_xrn=None, version = None, options=None):
        if options is None: options={}

        version_manager = VersionManager()
        version = version_manager.get_version(version)

        if not slice_xrn:
            rspec_version = version_manager._get_version(version.type, version.version, 'ad')
        else:
            rspec_version = version_manager._get_version(version.type, version.version, 'manifest')

        slice, slivers = self.get_slice_and_slivers(slice_xrn)

        rspec = RSpec(version=rspec_version, user_options=options)

        if slice and 'expires' in slice:
            rspec.xml.set('expires',  datetime_to_string(utcparse(slice['expires'])))

        if not options.get('list_leases') or options.get('list_leases') and options['list_leases'] != 'leases':
           nodes = self.get_nodes(slice_xrn, slice, slivers, options)
           rspec.version.add_nodes(nodes)
           # add sliver defaults
           default_sliver = slivers.get(None, [])
           if default_sliver:
              default_sliver_attribs = default_sliver.get('tags', [])
              for attrib in default_sliver_attribs:
                  logger.info(attrib)
                  rspec.version.add_default_sliver_attribute(attrib['tagname'], attrib['value'])
           # add wifi channels
           channels = self.get_channels(slice, options)
           rspec.version.add_channels(channels)

        if not options.get('list_leases') or options.get('list_leases') and options['list_leases'] != 'resources':
           leases_channels = self.get_leases_and_channels(slice, slice_xrn)
           rspec.version.add_leases(leases_channels)

        return rspec.toxml()
示例#43
0
文件: Renew.py 项目: kongseokhwan/sfa
    def call(self, urns, creds, expiration_time, options):


        # Find the valid credentials
        valid_creds = self.api.auth.checkCredentialsSpeaksFor(creds, 'renewsliver', urns,
                                                              check_sliver_callback = self.api.driver.check_sliver_credentials,
                                                              options=options)
        the_credential = Credential(cred=valid_creds[0])
        actual_caller_hrn = the_credential.actual_caller_hrn()
        self.api.logger.info("interface: %s\tcaller-hrn: %s\ttarget-urns: %s\texpiration:%s\tmethod-name: %s"%\
                             (self.api.interface, actual_caller_hrn, urns, expiration_time,self.name))


        # extend as long as possible : take the min of requested and now+SFA_MAX_SLICE_RENEW
        if options.get('geni_extend_alap'):
            # ignore requested time and set to max
            expiration_time = add_datetime(datetime.datetime.utcnow(), days=int(self.api.config.SFA_MAX_SLICE_RENEW))

        # Validate that the time does not go beyond the credential's expiration time
        requested_expire = utcparse(expiration_time)
        self.api.logger.info("requested_expire = %s"%requested_expire)
        credential_expire = the_credential.get_expiration()
        self.api.logger.info("credential_expire = %s"%credential_expire)
        max_renew_days = int(self.api.config.SFA_MAX_SLICE_RENEW)
        max_expire = datetime.datetime.utcnow() + datetime.timedelta (days=max_renew_days)
        if requested_expire > credential_expire:
            # used to throw an InsufficientRights exception here, this was not right
            self.api.logger.warning("Requested expiration %s, after credential expiration (%s) -> trimming to the latter/sooner"%\
                                    (requested_expire, credential_expire))
            requested_expire = credential_expire
        if requested_expire > max_expire:
            # likewise
            self.api.logger.warning("Requested expiration %s, after maximal expiration %s days (%s) -> trimming to the latter/sooner"%\
                                    (requested_expire, self.api.config.SFA_MAX_SLICE_RENEW,max_expire))
            requested_expire = max_expire

        return self.api.manager.Renew(self.api, urns, creds, requested_expire, options)
示例#44
0
    def fill_record_hrns(self, records):
        """
        convert nitos ids to hrns
        """

        # get ids
        slice_ids, user_ids, node_ids = [], [], []
        for record in records:
            if 'user_ids' in record:
                user_ids.extend(record['user_ids'])
            if 'slice_ids' in record:
                slice_ids.extend(record['slice_ids'])
            if 'node_ids' in record:
                node_ids.extend(record['node_ids'])

        # get nitos records
        slices, users, nodes = {}, {}, {}
        if node_ids:
            all_nodes = self.convert_id(self.shell.getNodes({}, []))
            node_list = [
                node for node in all_nodes if node['node_id'] in node_ids
            ]
            nodes = list_to_dict(node_list, 'node_id')
        if slice_ids:
            all_slices = self.convert_id(self.shell.getSlices({}, []))
            slice_list = [
                slice for slice in all_slices if slice['slice_id'] in slice_ids
            ]
            slices = list_to_dict(slice_list, 'slice_id')
        if user_ids:
            all_users = self.convert_id(self.shell.getUsers())
            user_list = [
                user for user in all_users if user['user_id'] in user_ids
            ]
            users = list_to_dict(user_list, 'user_id')

        # convert ids to hrns
        for record in records:
            # get all relevant data
            type = record['type']
            pointer = record['pointer']
            auth_hrn = self.hrn
            testbed_name = self.testbedInfo['name']
            if pointer == -1:
                continue
            if 'user_ids' in record:
                usernames = [users[user_id]['username'] for user_id in record['user_ids'] \
                          if user_id in  users]
                user_hrns = [
                    ".".join([auth_hrn, testbed_name, username])
                    for username in usernames
                ]
                record['users'] = user_hrns
            if 'slice_ids' in record:
                slicenames = [slices[slice_id]['slice_name'] for slice_id in record['slice_ids'] \
                              if slice_id in slices]
                slice_hrns = [
                    slicename_to_hrn(auth_hrn, slicename)
                    for slicename in slicenames
                ]
                record['slices'] = slice_hrns
            if 'node_ids' in record:
                hostnames = [nodes[node_id]['hostname'] for node_id in record['node_ids'] \
                             if node_id in nodes]
                node_hrns = [
                    hostname_to_hrn(auth_hrn, login_base, hostname)
                    for hostname in hostnames
                ]
                record['nodes'] = node_hrns

            if 'expires' in record:
                date = utcparse(record['expires'])
                datestring = datetime_to_string(date)
                record['expires'] = datestring

        return records
示例#45
0
文件: pldriver.py 项目: tubav/sfa
    def fill_record_hrns(self, records):
        """
        convert pl ids to hrns
        """

        # get ids
        slice_ids, person_ids, site_ids, node_ids = [], [], [], []
        for record in records:
            if 'site_id' in record:
                site_ids.append(record['site_id'])
            if 'site_ids' in record:
                site_ids.extend(record['site_ids'])
            if 'person_ids' in record:
                person_ids.extend(record['person_ids'])
            if 'slice_ids' in record:
                slice_ids.extend(record['slice_ids'])
            if 'node_ids' in record:
                node_ids.extend(record['node_ids'])

        # get pl records
        slices, persons, sites, nodes = {}, {}, {}, {}
        if site_ids:
            site_list = self.shell.GetSites(site_ids, ['site_id', 'login_base'])
            sites = list_to_dict(site_list, 'site_id')
        if person_ids:
            person_list = self.shell.GetPersons(person_ids, ['person_id', 'email'])
            persons = list_to_dict(person_list, 'person_id')
        if slice_ids:
            slice_list = self.shell.GetSlices(slice_ids, ['slice_id', 'name'])
            slices = list_to_dict(slice_list, 'slice_id')       
        if node_ids:
            node_list = self.shell.GetNodes(node_ids, ['node_id', 'hostname'])
            nodes = list_to_dict(node_list, 'node_id')
       
        # convert ids to hrns
        for record in records:
            # get all relevant data
            type = record['type']
            pointer = record['pointer']
            auth_hrn = self.hrn
            login_base = ''
            if pointer == -1:
                continue

            if 'site_id' in record:
                site = sites[record['site_id']]
                login_base = site['login_base']
                record['site'] = ".".join([auth_hrn, login_base])
            if 'person_ids' in record:
                emails = [persons[person_id]['email'] for person_id in record['person_ids'] \
                          if person_id in  persons]
                usernames = [email.split('@')[0] for email in emails]
                person_hrns = [".".join([auth_hrn, login_base, username]) for username in usernames]
                record['persons'] = person_hrns 
            if 'slice_ids' in record:
                slicenames = [slices[slice_id]['name'] for slice_id in record['slice_ids'] \
                              if slice_id in slices]
                slice_hrns = [slicename_to_hrn(auth_hrn, slicename) for slicename in slicenames]
                record['slices'] = slice_hrns
            if 'node_ids' in record:
                hostnames = [nodes[node_id]['hostname'] for node_id in record['node_ids'] \
                             if node_id in nodes]
                node_hrns = [hostname_to_hrn(auth_hrn, login_base, hostname) for hostname in hostnames]
                record['nodes'] = node_hrns
            if 'site_ids' in record:
                login_bases = [sites[site_id]['login_base'] for site_id in record['site_ids'] \
                               if site_id in sites]
                site_hrns = [".".join([auth_hrn, lbase]) for lbase in login_bases]
                record['sites'] = site_hrns

            if 'expires' in record:
                date = utcparse(record['expires'])
                datestring = datetime_to_string(date)
                record['expires'] = datestring 
            
        return records   
示例#46
0
文件: pldriver.py 项目: tubav/sfa
    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 person_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_xrn = Xrn(slice_urn, type='sliver', id=node['node_id'])
            sliver_xrn.set_authority(self.hrn)
             
            res['geni_urn'] = sliver_xrn.urn
            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
示例#47
0
    def decode(self):
        if not self.xml:
            return
        doc = parseString(self.xml)
        sigs = []
        signed_cred = doc.getElementsByTagName("signed-credential")

        # Is this a signed-cred or just a cred?
        if len(signed_cred) > 0:
            creds = signed_cred[0].getElementsByTagName("credential")
            signatures = signed_cred[0].getElementsByTagName("signatures")
            if len(signatures) > 0:
                sigs = signatures[0].getElementsByTagName("Signature")
        else:
            creds = doc.getElementsByTagName("credential")

        if creds is None or len(creds) == 0:
            # malformed cred file
            raise CredentialNotVerifiable(
                "Malformed XML: No credential tag found")

        # Just take the first cred if there are more than one
        cred = creds[0]

        self.set_refid(cred.getAttribute("xml:id"))
        self.set_expiration(utcparse(getTextNode(cred, "expires")))
        self.gidCaller = GID(string=getTextNode(cred, "owner_gid"))
        self.gidObject = GID(string=getTextNode(cred, "target_gid"))

        # Process privileges
        privs = cred.getElementsByTagName("privileges")[0]
        rlist = Rights()
        for priv in privs.getElementsByTagName("privilege"):
            kind = getTextNode(priv, "name")
            deleg = str2bool(getTextNode(priv, "can_delegate"))
            if kind == '*':
                # Convert * into the default privileges for the credential's type
                # Each inherits the delegatability from the * above
                _, type = urn_to_hrn(self.gidObject.get_urn())
                rl = determine_rights(type, self.gidObject.get_urn())
                for r in rl.rights:
                    r.delegate = deleg
                    rlist.add(r)
            else:
                rlist.add(Right(kind.strip(), deleg))
        self.set_privileges(rlist)

        # Is there a parent?
        parent = cred.getElementsByTagName("parent")
        if len(parent) > 0:
            parent_doc = parent[0].getElementsByTagName("credential")[0]
            parent_xml = parent_doc.toxml()
            self.parent = Credential(string=parent_xml)
            self.updateRefID()

        # Assign the signatures to the credentials
        for sig in sigs:
            Sig = Signature(string=sig.toxml())

            for cur_cred in self.get_credential_list():
                if cur_cred.get_refid() == Sig.get_refid():
                    cur_cred.set_signature(Sig)
示例#48
0
class Credential(object):

    ##
    # Create a Credential object
    #
    # @param create If true, create a blank x509 certificate
    # @param subject If subject!=None, create an x509 cert with the subject name
    # @param string If string!=None, load the credential from the string
    # @param filename If filename!=None, load the credential from the file
    # FIXME: create and subject are ignored!
    def __init__(self,
                 create=False,
                 subject=None,
                 string=None,
                 filename=None,
                 cred=None):
        self.gidCaller = None
        self.gidObject = None
        self.expiration = None
        self.privileges = None
        self.issuer_privkey = None
        self.issuer_gid = None
        self.issuer_pubkey = None
        self.parent = None
        self.signature = None
        self.xml = None
        self.refid = None
        self.legacy = None
        self.type = None
        self.version = None

        if cred:
            if isinstance(cred, StringTypes):
                string = cred
                self.type = 'geni_sfa'
                self.version = '1.0'
            elif isinstance(cred, dict):
                string = cred['geni_value']
                self.type = cred['geni_type']
                self.version = cred['geni_version']

        # Check if this is a legacy credential, translate it if so
        if string or filename:
            if string:
                str = string
            elif filename:
                str = file(filename).read()

            if str.strip().startswith("-----"):
                self.legacy = CredentialLegacy(False, string=str)
                self.translate_legacy(str)
            else:
                self.xml = str
                self.decode()

        # Find an xmlsec1 path
        self.xmlsec_path = ''
        paths = [
            '/usr/bin', '/usr/local/bin', '/bin', '/opt/bin', '/opt/local/bin'
        ]
        for path in paths:
            if os.path.isfile(path + '/' + 'xmlsec1'):
                self.xmlsec_path = path + '/' + 'xmlsec1'
                break

    def get_subject(self):
        subject = ""
        if not self.gidObject:
            self.decode()
        if self.gidObject:
            subject = self.gidObject.get_printable_subject()
        return subject

    # sounds like this should be __repr__ instead ??
    def get_summary_tostring(self):
        if not self.gidObject:
            self.decode()
        obj = self.gidObject.get_printable_subject()
        caller = self.gidCaller.get_printable_subject()
        exp = self.get_expiration()
        # Summarize the rights too? The issuer?
        return "[ Grant %s rights on %s until %s ]" % (caller, obj, exp)

    def get_signature(self):
        if not self.signature:
            self.decode()
        return self.signature

    def set_signature(self, sig):
        self.signature = sig

    ##
    # Translate a legacy credential into a new one
    #
    # @param String of the legacy credential

    def translate_legacy(self, str):
        legacy = CredentialLegacy(False, string=str)
        self.gidCaller = legacy.get_gid_caller()
        self.gidObject = legacy.get_gid_object()
        lifetime = legacy.get_lifetime()
        if not lifetime:
            self.set_expiration(datetime.datetime.utcnow() +
                                datetime.timedelta(
                                    seconds=DEFAULT_CREDENTIAL_LIFETIME))
        else:
            self.set_expiration(int(lifetime))
        self.lifeTime = legacy.get_lifetime()
        self.set_privileges(legacy.get_privileges())
        self.get_privileges().delegate_all_privileges(legacy.get_delegate())

    ##
    # Need the issuer's private key and name
    # @param key Keypair object containing the private key of the issuer
    # @param gid GID of the issuing authority

    def set_issuer_keys(self, privkey, gid):
        self.issuer_privkey = privkey
        self.issuer_gid = gid

    ##
    # Set this credential's parent
    def set_parent(self, cred):
        self.parent = cred
        self.updateRefID()

    ##
    # set the GID of the caller
    #
    # @param gid GID object of the caller

    def set_gid_caller(self, gid):
        self.gidCaller = gid
        # gid origin caller is the caller's gid by default
        self.gidOriginCaller = gid

    ##
    # get the GID of the object

    def get_gid_caller(self):
        if not self.gidCaller:
            self.decode()
        return self.gidCaller

    ##
    # set the GID of the object
    #
    # @param gid GID object of the object

    def set_gid_object(self, gid):
        self.gidObject = gid

    ##
    # get the GID of the object

    def get_gid_object(self):
        if not self.gidObject:
            self.decode()
        return self.gidObject

    ##
    # Expiration: an absolute UTC time of expiration (as either an int or string or datetime)
    #
    def set_expiration(self, expiration):
        if isinstance(expiration, (int, float)):
            self.expiration = datetime.datetime.fromtimestamp(expiration)
        elif isinstance(expiration, datetime.datetime):
            self.expiration = expiration
        elif isinstance(expiration, StringTypes):
            self.expiration = utcparse(expiration)
        else:
            logger.error("unexpected input type in Credential.set_expiration")

    ##
    # get the lifetime of the credential (always in datetime format)

    def get_expiration(self):
        if not self.expiration:
            self.decode()
        # at this point self.expiration is normalized as a datetime - DON'T call utcparse again
        return self.expiration

    ##
    # For legacy sake
    def get_lifetime(self):
        return self.get_expiration()

    ##
    # set the privileges
    #
    # @param privs either a comma-separated list of privileges of a Rights object

    def set_privileges(self, privs):
        if isinstance(privs, str):
            self.privileges = Rights(string=privs)
        else:
            self.privileges = privs

    ##
    # return the privileges as a Rights object

    def get_privileges(self):
        if not self.privileges:
            self.decode()
        return self.privileges

    ##
    # determine whether the credential allows a particular operation to be
    # performed
    #
    # @param op_name string specifying name of operation ("lookup", "update", etc)

    def can_perform(self, op_name):
        rights = self.get_privileges()

        if not rights:
            return False

        return rights.can_perform(op_name)

    ##
    # Encode the attributes of the credential into an XML string
    # This should be done immediately before signing the credential.
    # WARNING:
    # In general, a signed credential obtained externally should
    # not be changed else the signature is no longer valid.  So, once
    # you have loaded an existing signed credential, do not call encode() or sign() on it.

    def encode(self):
        # Create the XML document
        doc = Document()
        signed_cred = doc.createElement("signed-credential")

        # Declare namespaces
        # Note that credential/policy.xsd are really the PG schemas
        # in a PL namespace.
        # Note that delegation of credentials between the 2 only really works
        # cause those schemas are identical.
        # Also note these PG schemas talk about PG tickets and CM policies.
        signed_cred.setAttribute("xmlns:xsi",
                                 "http://www.w3.org/2001/XMLSchema-instance")
        signed_cred.setAttribute(
            "xsi:noNamespaceSchemaLocation",
            "http://www.planet-lab.org/resources/sfa/credential.xsd")
        signed_cred.setAttribute(
            "xsi:schemaLocation",
            "http://www.planet-lab.org/resources/sfa/ext/policy/1 http://www.planet-lab.org/resources/sfa/ext/policy/1/policy.xsd"
        )

        # PG says for those last 2:
        #        signed_cred.setAttribute("xsi:noNamespaceSchemaLocation", "http://www.protogeni.net/resources/credential/credential.xsd")
        #        signed_cred.setAttribute("xsi:schemaLocation", "http://www.protogeni.net/resources/credential/ext/policy/1 http://www.protogeni.net/resources/credential/ext/policy/1/policy.xsd")

        doc.appendChild(signed_cred)

        # Fill in the <credential> bit
        cred = doc.createElement("credential")
        cred.setAttribute("xml:id", self.get_refid())
        signed_cred.appendChild(cred)
        append_sub(doc, cred, "type", "privilege")
        append_sub(doc, cred, "serial", "8")
        append_sub(doc, cred, "owner_gid", self.gidCaller.save_to_string())
        append_sub(doc, cred, "owner_urn", self.gidCaller.get_urn())
        append_sub(doc, cred, "target_gid", self.gidObject.save_to_string())
        append_sub(doc, cred, "target_urn", self.gidObject.get_urn())
        append_sub(doc, cred, "uuid", "")
        if not self.expiration:
            self.set_expiration(datetime.datetime.utcnow() +
                                datetime.timedelta(
                                    seconds=DEFAULT_CREDENTIAL_LIFETIME))
        self.expiration = self.expiration.replace(microsecond=0)
        append_sub(doc, cred, "expires", self.expiration.isoformat())
        privileges = doc.createElement("privileges")
        cred.appendChild(privileges)

        if self.privileges:
            rights = self.get_privileges()
            for right in rights.rights:
                priv = doc.createElement("privilege")
                append_sub(doc, priv, "name", right.kind)
                append_sub(doc, priv, "can_delegate",
                           str(right.delegate).lower())
                privileges.appendChild(priv)

        # Add the parent credential if it exists
        if self.parent:
            sdoc = parseString(self.parent.get_xml())
            # If the root node is a signed-credential (it should be), then
            # get all its attributes and attach those to our signed_cred
            # node.
            # Specifically, PG and PLadd attributes for namespaces (which is reasonable),
            # and we need to include those again here or else their signature
            # no longer matches on the credential.
            # We expect three of these, but here we copy them all:
            #        signed_cred.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
            # and from PG (PL is equivalent, as shown above):
            #        signed_cred.setAttribute("xsi:noNamespaceSchemaLocation", "http://www.protogeni.net/resources/credential/credential.xsd")
            #        signed_cred.setAttribute("xsi:schemaLocation", "http://www.protogeni.net/resources/credential/ext/policy/1 http://www.protogeni.net/resources/credential/ext/policy/1/policy.xsd")

            # HOWEVER!
            # PL now also declares these, with different URLs, so
            # the code notices those attributes already existed with
            # different values, and complains.
            # This happens regularly on delegation now that PG and
            # PL both declare the namespace with different URLs.
            # If the content ever differs this is a problem,
            # but for now it works - different URLs (values in the attributes)
            # but the same actual schema, so using the PG schema
            # on delegated-to-PL credentials works fine.

            # Note: you could also not copy attributes
            # which already exist. It appears that both PG and PL
            # will actually validate a slicecred with a parent
            # signed using PG namespaces and a child signed with PL
            # namespaces over the whole thing. But I don't know
            # if that is a bug in xmlsec1, an accident since
            # the contents of the schemas are the same,
            # or something else, but it seems odd. And this works.
            parentRoot = sdoc.documentElement
            if parentRoot.tagName == "signed-credential" and parentRoot.hasAttributes(
            ):
                for attrIx in range(0, parentRoot.attributes.length):
                    attr = parentRoot.attributes.item(attrIx)
                    # returns the old attribute of same name that was
                    # on the credential
                    # Below throws InUse exception if we forgot to clone the attribute first
                    oldAttr = signed_cred.setAttributeNode(
                        attr.cloneNode(True))
                    if oldAttr and oldAttr.value != attr.value:
                        msg = "Delegating cred from owner %s to %s over %s:\n - Replaced attribute %s value '%s' with '%s'" % (
                            self.parent.gidCaller.get_urn(),
                            self.gidCaller.get_urn(), self.gidObject.get_urn(),
                            oldAttr.name, oldAttr.value, attr.value)
                        logger.warn(msg)
                        #raise CredentialNotVerifiable("Can't encode new valid delegated credential: %s" % msg)

            p_cred = doc.importNode(
                sdoc.getElementsByTagName("credential")[0], True)
            p = doc.createElement("parent")
            p.appendChild(p_cred)
            cred.appendChild(p)
        # done handling parent credential

        # Create the <signatures> tag
        signatures = doc.createElement("signatures")
        signed_cred.appendChild(signatures)

        # Add any parent signatures
        if self.parent:
            for cur_cred in self.get_credential_list()[1:]:
                sdoc = parseString(cur_cred.get_signature().get_xml())
                ele = doc.importNode(
                    sdoc.getElementsByTagName("Signature")[0], True)
                signatures.appendChild(ele)

        # Get the finished product
        self.xml = doc.toxml()

    def save_to_random_tmp_file(self):
        fp, filename = mkstemp(suffix='cred', text=True)
        fp = os.fdopen(fp, "w")
        self.save_to_file(filename, save_parents=True, filep=fp)
        return filename

    def save_to_file(self, filename, save_parents=True, filep=None):
        if not self.xml:
            self.encode()
        if filep:
            f = filep
        else:
            f = open(filename, "w")
        f.write(self.xml)
        f.close()

    def save_to_string(self, save_parents=True):
        if not self.xml:
            self.encode()
        return self.xml

    def get_refid(self):
        if not self.refid:
            self.refid = 'ref0'
        return self.refid

    def set_refid(self, rid):
        self.refid = rid

    ##
    # Figure out what refids exist, and update this credential's id
    # so that it doesn't clobber the others.  Returns the refids of
    # the parents.

    def updateRefID(self):
        if not self.parent:
            self.set_refid('ref0')
            return []

        refs = []

        next_cred = self.parent
        while next_cred:
            refs.append(next_cred.get_refid())
            if next_cred.parent:
                next_cred = next_cred.parent
            else:
                next_cred = None

        # Find a unique refid for this credential
        rid = self.get_refid()
        while rid in refs:
            val = int(rid[3:])
            rid = "ref%d" % (val + 1)

        # Set the new refid
        self.set_refid(rid)

        # Return the set of parent credential ref ids
        return refs

    def get_xml(self):
        if not self.xml:
            self.encode()
        return self.xml

    ##
    # Sign the XML file created by encode()
    #
    # WARNING:
    # In general, a signed credential obtained externally should
    # not be changed else the signature is no longer valid.  So, once
    # you have loaded an existing signed credential, do not call encode() or sign() on it.

    def sign(self):
        if not self.issuer_privkey or not self.issuer_gid:
            return
        doc = parseString(self.get_xml())
        sigs = doc.getElementsByTagName("signatures")[0]

        # Create the signature template to be signed
        signature = Signature()
        signature.set_refid(self.get_refid())
        sdoc = parseString(signature.get_xml())
        sig_ele = doc.importNode(
            sdoc.getElementsByTagName("Signature")[0], True)
        sigs.appendChild(sig_ele)

        self.xml = doc.toxml()

        # Split the issuer GID into multiple certificates if it's a chain
        chain = GID(filename=self.issuer_gid)
        gid_files = []
        while chain:
            gid_files.append(chain.save_to_random_tmp_file(False))
            if chain.get_parent():
                chain = chain.get_parent()
            else:
                chain = None

        # Call out to xmlsec1 to sign it
        ref = 'Sig_%s' % self.get_refid()
        filename = self.save_to_random_tmp_file()
        signed = os.popen('%s --sign --node-id "%s" --privkey-pem %s,%s %s' \
                 % (self.xmlsec_path, ref, self.issuer_privkey, ",".join(gid_files), filename)).read()
        os.remove(filename)

        for gid_file in gid_files:
            os.remove(gid_file)

        self.xml = signed

        # This is no longer a legacy credential
        if self.legacy:
            self.legacy = None

        # Update signatures
        self.decode()

    ##
    # Retrieve the attributes of the credential from the XML.
    # This is automatically called by the various get_* methods of
    # this class and should not need to be called explicitly.

    def decode(self):
        if not self.xml:
            return

        doc = None
        try:
            doc = parseString(self.xml)
        except ExpatError, e:
            raise CredentialNotVerifiable("Malformed credential")
        doc = parseString(self.xml)
        sigs = []
        signed_cred = doc.getElementsByTagName("signed-credential")

        # Is this a signed-cred or just a cred?
        if len(signed_cred) > 0:
            creds = signed_cred[0].getElementsByTagName("credential")
            signatures = signed_cred[0].getElementsByTagName("signatures")
            if len(signatures) > 0:
                sigs = signatures[0].getElementsByTagName("Signature")
        else:
            creds = doc.getElementsByTagName("credential")

        if creds is None or len(creds) == 0:
            # malformed cred file
            raise CredentialNotVerifiable(
                "Malformed XML: No credential tag found")

        # Just take the first cred if there are more than one
        cred = creds[0]

        self.set_refid(cred.getAttribute("xml:id"))
        self.set_expiration(utcparse(getTextNode(cred, "expires")))
        self.gidCaller = GID(string=getTextNode(cred, "owner_gid"))
        self.gidObject = GID(string=getTextNode(cred, "target_gid"))

        # Process privileges
        privs = cred.getElementsByTagName("privileges")[0]
        rlist = Rights()
        for priv in privs.getElementsByTagName("privilege"):
            kind = getTextNode(priv, "name")
            deleg = str2bool(getTextNode(priv, "can_delegate"))
            if kind == '*':
                # Convert * into the default privileges for the credential's type
                # Each inherits the delegatability from the * above
                _, type = urn_to_hrn(self.gidObject.get_urn())
                rl = determine_rights(type, self.gidObject.get_urn())
                for r in rl.rights:
                    r.delegate = deleg
                    rlist.add(r)
            else:
                rlist.add(Right(kind.strip(), deleg))
        self.set_privileges(rlist)

        # Is there a parent?
        parent = cred.getElementsByTagName("parent")
        if len(parent) > 0:
            parent_doc = parent[0].getElementsByTagName("credential")[0]
            parent_xml = parent_doc.toxml()
            self.parent = Credential(string=parent_xml)
            self.updateRefID()

        # Assign the signatures to the credentials
        for sig in sigs:
            Sig = Signature(string=sig.toxml())

            for cur_cred in self.get_credential_list():
                if cur_cred.get_refid() == Sig.get_refid():
                    cur_cred.set_signature(Sig)
示例#49
0
    def GetCredential(self, api, xrn, type, caller_xrn=None):
        # convert xrn to hrn
        if type:
            hrn = urn_to_hrn(xrn)[0]
        else:
            hrn, type = urn_to_hrn(xrn)

        # Is this a root or sub authority
        auth_hrn = api.auth.get_authority(hrn)
        if not auth_hrn or hrn == api.config.SFA_INTERFACE_HRN:
            auth_hrn = hrn
        auth_info = api.auth.get_auth_info(auth_hrn)
        # get record info
        filter = {'hrn': hrn}
        if type:
            filter['type'] = type
        record = dbsession.query(RegRecord).filter_by(**filter).first()
        if not record:
            raise RecordNotFound("hrn=%s, type=%s" % (hrn, type))

        # verify_cancreate_credential requires that the member lists
        # (researchers, pis, etc) be filled in
        logger.debug("get credential before augment dict, keys=%s" %
                     record.__dict__.keys())
        self.driver.augment_records_with_testbed_info(record.__dict__)
        logger.debug("get credential after augment dict, keys=%s" %
                     record.__dict__.keys())
        if not self.driver.is_enabled(record.__dict__):
            raise AccountNotEnabled(
                ": PlanetLab account %s is not enabled. Please contact your site PI"
                % (record.email))

        # get the callers gid
        # if caller_xrn is not specified assume the caller is the record
        # object itself.
        if not caller_xrn:
            caller_hrn = hrn
            caller_gid = record.get_gid_object()
        else:
            caller_hrn, caller_type = urn_to_hrn(caller_xrn)
            caller_filter = {'hrn': caller_hrn}
            if caller_type:
                caller_filter['type'] = caller_type
            caller_record = dbsession.query(RegRecord).filter_by(
                **caller_filter).first()
            if not caller_record:
                raise RecordNotFound(
                    "Unable to associated caller (hrn=%s, type=%s) with credential for (hrn: %s, type: %s)"
                    % (caller_hrn, caller_type, hrn, type))
            caller_gid = GID(string=caller_record.gid)

        object_hrn = record.get_gid_object().get_hrn()
        rights = api.auth.determine_user_rights(caller_hrn, record.todict())
        # make sure caller has rights to this object
        if rights.is_empty():
            raise PermissionError(caller_hrn + " has no rights to " +
                                  record.hrn)

        object_gid = GID(string=record.gid)
        new_cred = Credential(subject=object_gid.get_subject())
        new_cred.set_gid_caller(caller_gid)
        new_cred.set_gid_object(object_gid)
        new_cred.set_issuer_keys(auth_info.get_privkey_filename(),
                                 auth_info.get_gid_filename())
        #new_cred.set_pubkey(object_gid.get_pubkey())
        new_cred.set_privileges(rights)
        new_cred.get_privileges().delegate_all_privileges(True)
        if hasattr(record, 'expires'):
            date = utcparse(record.expires)
            expires = datetime_to_epoch(date)
            new_cred.set_expiration(int(expires))
        auth_kind = "authority,ma,sa"
        # Parent not necessary, verify with certs
        #new_cred.set_parent(api.auth.hierarchy.get_auth_cred(auth_hrn, kind=auth_kind))
        new_cred.encode()
        new_cred.sign()

        return new_cred.save_to_string(save_parents=True)
示例#50
0
    def describe(self, urns, version=None, options={}):
        """
        Retrieve a manifest RSpec describing the resources contained by the
        named entities, e.g. a single slice or a set of the slivers in a slice.
        This listing and description should be sufficiently descriptive to allow
        experimenters to use the resources.

        :param urns: If a slice urn is supplied and there are no slivers in the
            given slice at this aggregate, then geni_rspec shall be a valid
            manifest RSpec, containing no node elements - no resources.
        :type urns: list  or strings
        :param options: various options. the valid options are: {boolean
            geni_compressed <optional>; struct geni_rspec_version { string type;
            #case insensitive , string version; # case insensitive}}
        :type options: dictionary

        :returns: On success returns the following dictionary {geni_rspec:
            <geni.rspec, a Manifest RSpec>, geni_urn: <string slice urn of the
            containing slice>, geni_slivers:{ geni_sliver_urn:
            <string sliver urn>, geni_expires:  <dateTime.rfc3339 allocation
            expiration string, as in geni_expires from SliversStatus>,
            geni_allocation_status: <string sliver state - e.g. geni_allocated
            or geni_provisioned >, geni_operational_status:
            <string sliver operational state>, geni_error: <optional string.
            The field may be omitted entirely but may not be null/None,
            explaining any failure for a sliver.>}

        .. seealso:: http://groups.geni.net/geni/wiki/GAPI_AM_API_V3#Describe
        .. seealso:: http://groups.geni.net/geni/wiki/GAPI_AM_API_V3/CommonConcepts#urns
        """
        version_manager = VersionManager()
        version = version_manager.get_version(version)
        rspec_version = version_manager._get_version(version.type,
                                                     version.version,
                                                     'manifest')
        rspec = RSpec(version=rspec_version, user_options=options)

        # get slivers
        geni_slivers = []
        slivers = self.get_slivers(urns, options)
        if slivers:
            rspec_expires = datetime_to_string(utcparse(slivers[0]['expires']))
        else:
            rspec_expires = datetime_to_string(utcparse(time.time()))
        rspec.xml.set('expires', rspec_expires)

        # lookup the sliver allocations
        geni_urn = urns[0]
        sliver_ids = [sliver['sliver_id'] for sliver in slivers]
        logger.debug(" Cortexlabaggregate.PY \tDescribe  sliver_ids %s " %
                     (sliver_ids))
        constraint = SliverAllocation.sliver_id.in_(sliver_ids)
        query = self.driver.api.dbsession().query(SliverAllocation)
        sliver_allocations = query.filter((constraint)).all()
        logger.debug(
            " Cortexlabaggregate.PY \tDescribe  sliver_allocations %s " %
            (sliver_allocations))
        sliver_allocation_dict = {}
        for sliver_allocation in sliver_allocations:
            geni_urn = sliver_allocation.slice_urn
            sliver_allocation_dict[sliver_allocation.sliver_id] = \
                                                            sliver_allocation

        # add slivers
        nodes_dict = {}
        for sliver in slivers:
            nodes_dict[sliver['node_id']] = sliver
        rspec_nodes = []
        for sliver in slivers:
            rspec_node = self.sliver_to_rspec_node(sliver,
                                                   sliver_allocation_dict)
            rspec_nodes.append(rspec_node)
            logger.debug(
                " Cortexlabaggregate.PY \tDescribe  sliver_allocation_dict %s "
                % (sliver_allocation_dict))
            geni_sliver = self.rspec_node_to_geni_sliver(
                rspec_node, sliver_allocation_dict)
            geni_slivers.append(geni_sliver)

        logger.debug(" Cortexlabaggregate.PY \tDescribe rspec_nodes %s\
                        rspec %s " % (rspec_nodes, rspec))
        rspec.version.add_nodes(rspec_nodes)

        return {
            'geni_urn': geni_urn,
            'geni_rspec': rspec.toxml(),
            'geni_slivers': geni_slivers
        }
示例#51
0
    def describe(self, urns, version=None, options={}):
        version_manager = VersionManager()
        version = version_manager.get_version(version)
        rspec_version = version_manager._get_version(version.type,
                                                     version.version,
                                                     'manifest')
        rspec = RSpec(version=rspec_version, user_options=options)

        # get slivers
        geni_slivers = []
        slivers = self.get_slivers(urns, options)
        if slivers:
            rspec_expires = datetime_to_string(utcparse(slivers[0]['expires']))
        else:
            rspec_expires = datetime_to_string(utcparse(time.time()))
        rspec.xml.set('expires', rspec_expires)

        # lookup the sliver allocations
        geni_urn = urns[0]
        sliver_ids = [sliver['sliver_id'] for sliver in slivers]
        constraint = SliverAllocation.sliver_id.in_(sliver_ids)
        sliver_allocations = self.driver.api.dbsession().query(
            SliverAllocation).filter(constraint)
        sliver_allocation_dict = {}
        for sliver_allocation in sliver_allocations:
            geni_urn = sliver_allocation.slice_urn
            sliver_allocation_dict[
                sliver_allocation.sliver_id] = sliver_allocation

        if not options.get(
                'list_leases') or options['list_leases'] != 'leases':
            # add slivers
            site_ids = []
            interface_ids = []
            tag_ids = []
            nodes_dict = {}
            for sliver in slivers:
                site_ids.append(sliver['site_id'])
                interface_ids.extend(sliver['interface_ids'])
                tag_ids.extend(sliver['node_tag_ids'])
                nodes_dict[sliver['node_id']] = sliver
            sites = self.get_sites({'site_id': site_ids})
            interfaces = self.get_interfaces({'interface_id': interface_ids})
            node_tags = self.get_node_tags({'node_tag_id': tag_ids})
            pl_initscripts = self.get_pl_initscripts()
            rspec_nodes = []
            for sliver in slivers:
                if sliver['slice_ids_whitelist'] and sliver[
                        'slice_id'] not in sliver['slice_ids_whitelist']:
                    continue
                rspec_node = self.sliver_to_rspec_node(sliver, sites,
                                                       interfaces, node_tags,
                                                       pl_initscripts,
                                                       sliver_allocation_dict)
                # manifest node element shouldn't contain available attribute
                rspec_node.pop('available')
                rspec_nodes.append(rspec_node)
                geni_sliver = self.rspec_node_to_geni_sliver(
                    rspec_node, sliver_allocation_dict)
                geni_slivers.append(geni_sliver)
            rspec.version.add_nodes(rspec_nodes)

            # add sliver defaults
            #default_sliver = slivers.get(None, [])
            #if default_sliver:
            #    default_sliver_attribs = default_sliver.get('tags', [])
            #    for attrib in default_sliver_attribs:
            #        rspec.version.add_default_sliver_attribute(attrib['tagname'], attrib['value'])

            # add links
            links = self.get_links(sites, nodes_dict, interfaces)
            rspec.version.add_links(links)

        if not options.get(
                'list_leases') or options['list_leases'] != 'resources':
            if slivers:
                leases = self.get_leases(slivers[0])
                rspec.version.add_leases(leases)

        return {
            'geni_urn': geni_urn,
            'geni_rspec': rspec.toxml(),
            'geni_slivers': geni_slivers
        }
示例#52
0
文件: pldriver.py 项目: gnogueras/sfa
    def fill_record_hrns(self, records):
        """
        convert pl ids to hrns
        """

        # get ids
        slice_ids, person_ids, site_ids, node_ids = [], [], [], []
        for record in records:
            if 'site_id' in record:
                site_ids.append(record['site_id'])
            if 'site_ids' in record:
                site_ids.extend(record['site_ids'])
            if 'person_ids' in record:
                person_ids.extend(record['person_ids'])
            if 'slice_ids' in record:
                slice_ids.extend(record['slice_ids'])
            if 'node_ids' in record:
                node_ids.extend(record['node_ids'])

        # get pl records
        slices, persons, sites, nodes = {}, {}, {}, {}
        if site_ids:
            site_list = self.shell.GetSites(
                {
                    'peer_id': None,
                    'site_id': site_ids
                }, ['site_id', 'login_base'])
            sites = list_to_dict(site_list, 'site_id')
        if person_ids:
            person_list = self.shell.GetPersons(
                {
                    'peer_id': None,
                    'person_id': person_ids
                }, ['person_id', 'email'])
            persons = list_to_dict(person_list, 'person_id')
        if slice_ids:
            slice_list = self.shell.GetSlices(
                {
                    'peer_id': None,
                    'slice_id': slice_ids
                }, ['slice_id', 'name'])
            slices = list_to_dict(slice_list, 'slice_id')
        if node_ids:
            node_list = self.shell.GetNodes(
                {
                    'peer_id': None,
                    'node_id': node_ids
                }, ['node_id', 'hostname'])
            nodes = list_to_dict(node_list, 'node_id')

        # convert ids to hrns
        for record in records:
            # get all relevant data
            type = record['type']
            pointer = record['pointer']
            auth_hrn = self.hrn
            login_base = ''
            if pointer == -1:
                continue

            if 'site_id' in record:
                site = sites[record['site_id']]
                login_base = site['login_base']
                record['site'] = ".".join([auth_hrn, login_base])
            if 'person_ids' in record:
                emails = [persons[person_id]['email'] for person_id in record['person_ids'] \
                          if person_id in  persons]
                usernames = [email.split('@')[0] for email in emails]
                person_hrns = [
                    ".".join([auth_hrn, login_base, username])
                    for username in usernames
                ]
                record['persons'] = person_hrns
            if 'slice_ids' in record:
                slicenames = [slices[slice_id]['name'] for slice_id in record['slice_ids'] \
                              if slice_id in slices]
                slice_hrns = [
                    slicename_to_hrn(auth_hrn, slicename)
                    for slicename in slicenames
                ]
                record['slices'] = slice_hrns
            if 'node_ids' in record:
                hostnames = [nodes[node_id]['hostname'] for node_id in record['node_ids'] \
                             if node_id in nodes]
                node_hrns = [
                    hostname_to_hrn(auth_hrn, login_base, hostname)
                    for hostname in hostnames
                ]
                record['nodes'] = node_hrns
            if 'site_ids' in record:
                login_bases = [sites[site_id]['login_base'] for site_id in record['site_ids'] \
                               if site_id in sites]
                site_hrns = [
                    ".".join([auth_hrn, lbase]) for lbase in login_bases
                ]
                record['sites'] = site_hrns

            if 'expires' in record:
                date = utcparse(record['expires'])
                datestring = datetime_to_string(date)
                record['expires'] = datestring

        return records
示例#53
0
    def fill_record_hrns(self, records):
        """
        Convert C-Lab names of the records in the list to hrns
        
        :param record: list of SFA records whose names are converted
        :type list
        
        :returns list of SFA records filled with hrn
        :rtype list 
        """
        # get ids
        slice_ids, user_ids, node_ids = [], [], []
        for record in records:
            if 'user_ids' in record:
                user_ids.extend(record['user_ids'])
            if 'slice_ids' in record:
                slice_ids.extend(record['slice_ids'])
            if 'node_ids' in record:
                node_ids.extend(record['node_ids'])
        
        # get clab records
        nodes, slices, users, keys = {}, {}, {}, {}
        if node_ids:
            all_nodes = self.convert_id(self.driver.testbed_shell.get_nodes())
            node_list =  [node for node in all_nodes if node['id'] in node_ids]
            nodes = self.list_to_dict(node_list, 'id')
            
        if slice_ids:
            all_slices = self.convert_id(self.driver.testbed_shell.get_slices())
            slice_list =  [slice for slice in all_slices if slice['id'] in slice_ids]
            slices = self.list_to_dict(slice_list, 'id')
            
        if user_ids:
            all_users = self.convert_id(self.driver.testbed_shell.get_users())
            user_list = [user for user in all_users if user['id'] in user_ids] 
            users = self.list_to_dict(user_list, 'id')       

        # convert ids to hrns
        for record in records:
            # get all relevant data
            type = record['type']
            pointer = record['pointer']
            auth_hrn = self.driver.AUTHORITY
            if pointer == -1:
                continue
            if 'user_ids' in record:
                usernames = [users[user_id]['name'] for user_id in record['user_ids'] if user_id in  users]
                user_hrns = [".".join([auth_hrn, username]) for username in usernames]
                record['users'] = user_hrns 
            if 'slice_ids' in record:
                slicenames = [slices[slice_id]['name'] for slice_id in record['slice_ids'] if slice_id in slices]
                slice_hrns = [slicename_to_hrn(slicename, auth_hrn) for slicename in slicenames]
                record['slices'] = slice_hrns
            if 'node_ids' in record:
                hostnames = [nodes[node_id]['name'] for node_id in record['node_ids'] if node_id in nodes]
                node_hrns = [hostname_to_hrn(auth_hrn, hostname) for hostname in hostnames]
                record['nodes'] = node_hrns

            if 'expires' in record:
                date = utcparse(record['expires'])
                datestring = datetime_to_string(date)
                record['expires'] = datestring 
            
        return records