Esempio n. 1
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)
Esempio n. 2
0
    def update (self, old_sfa_record, new_sfa_record, hrn, new_key):
        '''
        Update a object (record) in the registry. This might also update the tested information
        associated with the record. 
        
        :param old_sfa_record: SFA record of the entity being updated
        :type dict
        
        :param new_sfa_record: new SFA record to update the old SFA record
        :type dict
        
        :param hrn: hrn of the resource being updated
        :type string
        
        :param new_key: new public key for the user (if apply)
        :type string
        
        :returns boolean value indicating the success of the operation
        :rtype boolean
        '''
        pointer = old_sfa_record['pointer']
        if isinstance(pointer, str):
            pointer = int(pointer)
        type = old_sfa_record['type']
        
        clab_updated_fields = self.sfa_fields_to_clab_fields(type, hrn, new_sfa_record)

        # new_key implemented for users only
        #if new_key and type not in [ 'user' ]:
        #    raise UnknownSfaType(type)

        if type == "slice":
            filtered_slices = self.driver.testbed_shell.get_slices({'id': pointer})
            if not filtered_slices:
                raise RecordNotFound('Slice with id %s'%pointer) # Slice not found 
            slice_uri = filtered_slices[0]['uri']
            return self.driver.testbed_shell.update_slice(slice_uri, clab_updated_fields)
    
        elif type == "user":
            filtered_users = self.driver.testbed_shell.get_users({'id': pointer})
            if not filtered_slices:
                raise RecordNotFound('User with id %s'%pointer) # User not found 
            user_uri = filtered_users[0]['uri']
            return self.driver.testbed_shell.update_user(user_uri, clab_updated_fields) 
    
            #if new_key:
                # needs to be improved 
                #self.shell.addUserKey({'user_id': pointer, 'key': new_key}) 
    
        elif type == "node":
            filtered_nodes = self.driver.testbed_shell.get_nodes({'id': pointer})
            if not filtered_nodes:
                raise RecordNotFound('Node with id %s'%pointer) # Node not found 
            node_uri = filtered_nodes[0]['uri']
            return self.driver.testbed_shell.update_node(node_uri, clab_updated_fields)

        return False
Esempio n. 3
0
    def _getCredentialRaw(self):
        """
        Get our current credential directly from the local registry.
        """

        hrn = self.hrn
        auth_hrn = self.auth.get_authority(hrn)

        # is this a root or sub authority
        if not auth_hrn or hrn == self.config.SFA_INTERFACE_HRN:
            auth_hrn = hrn
        auth_info = self.auth.get_auth_info(auth_hrn)
        # xxx although unlikely we might want to check for a potential leak
        dbsession = self.dbsession()
        from sfa.storage.model import RegRecord
        record = dbsession.query(RegRecord).filter_by(type='authority+sa',
                                                      hrn=hrn).first()
        if not record:
            raise RecordNotFound(hrn)
        type = record.type
        object_gid = record.get_gid_object()
        new_cred = Credential(subject=object_gid.get_subject())
        new_cred.set_gid_caller(object_gid)
        new_cred.set_gid_object(object_gid)
        new_cred.set_issuer_keys(auth_info.get_privkey_filename(),
                                 auth_info.get_gid_filename())

        r1 = determine_rights(type, hrn)
        new_cred.set_privileges(r1)
        new_cred.encode()
        new_cred.sign()

        return new_cred
Esempio n. 4
0
    def GetSelfCredential(certificate, xnr, type):
        if type:
            hrn = urn_to_hrn(xrn)[0]
        else:
            hrn, type = urn_to_hrn(xrn)

        origin_hrn = Certificate(string=cert).get_subject()
        ### authenticate the gid
        # import here so we can load this module at build-time for sfa2wsdl
        #from sfa.storage.alchemy import dbsession
        from sfa.storage.model import RegRecord

        # xxx-local - the current code runs Resolve, which would forward to 
        # another registry if needed
        # I wonder if this is truly the intention, or shouldn't we instead 
        # only look in the local db ?
        records = self.api.manager.Resolve(self.api, xrn, type, details=False)
        if not records:
            raise RecordNotFound(hrn)

        record_obj = RegRecord (dict=records[0])
        # xxx-local the local-only version would read 
        #record_obj = dbsession.query(RegRecord).filter_by(hrn=hrn).first()
        #if not record_obj: raise RecordNotFound(hrn)
        gid = record_obj.get_gid_object()
        gid_str = gid.save_to_string(save_parents=True)
        self.api.auth.authenticateGid(gid_str, [cert, type, hrn])
        # authenticate the certificate against the gid in the db
        certificate = Certificate(string=cert)
        if not certificate.is_pubkey(gid.get_pubkey()):
            for (obj,name) in [ (certificate,"CERT"), (gid,"GID"), ]:
                if hasattr (obj,'filename'):
            raise ConnectionKeyGIDMismatch(gid.get_subject())

        return self.api.manager.GetCredential(self.api, xrn, type)
Esempio n. 5
0
    def shutdown(self, xrn, options={}):
        hrn, _ = urn_to_hrn(xrn)
        top_auth_hrn = top_auth(hrn)
        site_hrn = '.'.join(hrn.split('.')[:-1])
        slice_part = hrn.split('.')[-1]
        if top_auth_hrn == self.hrn:
            login_base = slice_hrn.split('.')[-2][:12]
        else:
            login_base = hash_loginbase(site_hrn)

        slicename = '_'.join([login_base, slice_part])

        slices = self.shell.GetSlices({
            'peer_id': None,
            'name': slicename
        }, ['slice_id'])
        if not slices:
            raise RecordNotFound(slice_hrn)
        slice_id = slices[0]['slice_id']
        slice_tags = self.shell.GetSliceTags({
            'slice_id': slice_id,
            'tagname': 'enabled'
        })
        if not slice_tags:
            self.shell.AddSliceTag(slice_id, 'enabled', '0')
        elif slice_tags[0]['value'] != "0":
            tag_id = slice_tags[0]['slice_tag_id']
            self.shell.UpdateSliceTag(tag_id, '0')
        return 1
Esempio n. 6
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
Esempio n. 7
0
 def shutdown(self, xrn, options={}):
     xrn = DummyXrn(xrn=xrn, type='slice')
     slicename = xrn.pl_slicename()
     slices = self.shell.GetSlices({'name': slicename}, ['slice_id'])
     if not slices:
         raise RecordNotFound(slice_hrn)
     slice_id = slices[0]['slice_id']
     slice_tags = self.shell.GetSliceTags({
         'slice_id': slice_id,
         'tagname': 'enabled'
     })
     if not slice_tags:
         self.shell.AddSliceTag(slice_id, 'enabled', '0')
     elif slice_tags[0]['value'] != "0":
         tag_id = slice_tags[0]['slice_tag_id']
         self.shell.UpdateSliceTag(tag_id, '0')
     return 1
Esempio n. 8
0
    def call(self, xrns, creds):
        # validate the credential
        valid_creds = self.api.auth.checkCredentials(creds, 'getgids')
        # xxxpylintxxx origin_hrn is unused..
        origin_hrn = Credential(string=valid_creds[0]).get_gid_caller().get_hrn()
        
        # resolve the record
        records = self.api.manager.Resolve(self.api, xrns, details = False)
        if not records:
            raise RecordNotFound(xrns)

        allowed_fields =  ['hrn', 'type', 'gid']
        for record in records:
            for key in record.keys():
                if key not in allowed_fields:
                    del(record[key])
        return records    
Esempio n. 9
0
    def Remove(self, api, xrn, origin_hrn=None):
        dbsession = api.dbsession()
        hrn = xrn.get_hrn()
        type = xrn.get_type()
        request = dbsession.query(RegRecord).filter_by(hrn=hrn)
        if type and type not in ['all', '*']:
            request = request.filter_by(type=type)

        record = request.first()
        if not record:
            msg = "Could not find hrn %s" % hrn
            if type: msg += " type=%s" % type
            raise RecordNotFound(msg)

        type = record.type
        if type not in ['slice', 'user', 'node', 'authority']:
            raise UnknownSfaType(type)

        credential = api.getCredential()
        registries = api.registries

        # Try to remove the object from the PLCDB of federated agg.
        # This is attempted before removing the object from the local agg's PLCDB and sfa table
        if hrn.startswith(api.hrn) and type in ['user', 'slice', 'authority']:
            for registry in registries:
                if registry not in [api.hrn]:
                    try:
                        result = registries[registry].remove_peer_object(
                            credential, record, origin_hrn)
                    except:
                        pass

        # call testbed callback first
        # IIUC this is done on the local testbed TOO because of the refreshpeer link
        if not api.driver.remove(record.__dict__):
            logger.warning("driver.remove failed")

        # delete from sfa db
        dbsession.delete(record)
        dbsession.commit()

        return 1
Esempio n. 10
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)
Esempio n. 11
0
 def update_relation (self, subject_type, target_type, relation_name, subject_id, target_ids):
     '''
     Update the relations between objects in the testbed. 
     Typically it is used to add/change roles of users with respect to some resources, 
     e.g. defined the role of researcher for a user in a given slice. 
         
     :param subject_type: resource type (slice, node...) for which the relation is being updated. Subject of the relation update.
     :type string
     
     :param target_type: resource/entity (user) whose relation with respect to the resource indicated in subject is being changed. 
         Target of the relation updated.
     :type string
     
     :param relation_name: new role for the target entity with respect to the subject resource. (researcher, owner...)
     :type string
     
     :param subject_id: ID of the subject resource for which the relation is being changed (id of the slice)
     :type string OR int
     
     :param target_ids: ID or list of IDs for the entity or entities whose relation with respect to the subject resource is being updated. 
     :type list
     
     :returns boolean value indicating the success of the operation
     :rtype boolean
     '''
     # Supported: change relation type of a User for a Slice
     if subject_type =='slice' and target_type == 'user':
         # obtain subject slice
         if isinstance(subject_id, str):
             subject_id = int(subject_id)
         filtered_subjects = self.driver.testbed_shell.get_slices ({'id': subject_id})
         if not filtered_subjects:
             raise RecordNotFound('Slice with id %s'%subject_id)
         subject = filtered_subjects[0]
         # Obtain group_uri the slice belongs to 
         group_uri = subject['group']['uri']
         
         if not isinstance(target_ids, list):
             target_ids = [target_ids]
         # For each target_id (user_id) that needs its role to be changed
         for target_id in target_ids:
             # Get the current group roles of the user
             if isinstance(target_id, str):
                 target_id = int(target_id)
             user = self.driver.testbed_shell.get_users({'id':target_id})[0]
             group_roles = user['group_roles']
             # Change the roles according to the relation_update for the user
             # The roles of the group that the subject slice belogs to 
             for role in group_roles:
                 # Select the group role of the group that the slice belongs to
                 if role['group']['uri']==group_uri:
                     # Prepare new relation
                     if relation_name == 'researcher':
                         role['is_researcher']=True
                     elif relation_name == 'technician':
                         role['is_technician']=True
                     break
             # Update the user with the new group_roles 
             return self.driver.testbed_shell.update_user(user['uri'], {'group_roles':group_roles})
             
     else: 
         raise SfaNotImplemented('Registry')
Esempio n. 12
0
    def call(self, cert, xrn, type):
        """
        GetSelfCredential a degenerate version of GetCredential used by a client
        to get his initial credential when de doesnt have one. This is the same as
        GetCredential(..., cred = None, ...)

        The registry ensures that the client is the principal that is named by
        (type, name) by comparing the public key in the record's  GID to the
        private key used to encrypt the client side of the HTTPS connection. Thus
        it is impossible for one principal to retrieve another principal's
        credential without having the appropriate private key.

        @param type type of object (user | slice | sa | ma | node)
        @param hrn human readable name of authority to list
        @return string representation of a credential object
        """
        if type:
            hrn = urn_to_hrn(xrn)[0]
        else:
            hrn, type = urn_to_hrn(xrn)
        self.api.auth.verify_object_belongs_to_me(hrn)

        origin_hrn = Certificate(string=cert).get_subject()
        self.api.logger.info(
            "interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s" %
            (self.api.interface, origin_hrn, hrn, self.name))

        ### authenticate the gid
        # import here so we can load this module at build-time for sfa2wsdl
        #from sfa.storage.alchemy import dbsession
        from sfa.storage.model import RegRecord

        # xxx-local - the current code runs Resolve, which would forward to
        # another registry if needed
        # I wonder if this is truly the intention, or shouldn't we instead
        # only look in the local db ?
        records = self.api.manager.Resolve(self.api, xrn, type, details=False)
        if not records:
            raise RecordNotFound(hrn)

        record_obj = RegRecord(dict=records[0])
        # xxx-local the local-only version would read
        #record_obj = dbsession.query(RegRecord).filter_by(hrn=hrn).first()
        #if not record_obj: raise RecordNotFound(hrn)
        gid = record_obj.get_gid_object()
        gid_str = gid.save_to_string(save_parents=True)
        self.api.auth.authenticateGid(gid_str, [cert, type, hrn])
        # authenticate the certificate against the gid in the db
        certificate = Certificate(string=cert)
        if not certificate.is_pubkey(gid.get_pubkey()):
            for (obj, name) in [
                (certificate, "CERT"),
                (gid, "GID"),
            ]:
                self.api.logger.debug(
                    "ConnectionKeyGIDMismatch, %s pubkey: %s" %
                    (name, obj.get_pubkey().get_pubkey_string()))
                self.api.logger.debug("ConnectionKeyGIDMismatch, %s dump: %s" %
                                      (name, obj.dump_string()))
                if hasattr(obj, 'filename'):
                    self.api.logger.debug(
                        "ConnectionKeyGIDMismatch, %s filename: %s" %
                        (name, obj.filename))
            raise ConnectionKeyGIDMismatch(gid.get_subject())

        return self.api.manager.GetCredential(self.api, xrn, type)
Esempio n. 13
0
    def Resolve(self, api, xrns, type=None, details=False):

        if not isinstance(xrns, types.ListType):
            # try to infer type if not set and we get a single input
            if not type:
                type = Xrn(xrns).get_type()
            xrns = [xrns]
        hrns = [urn_to_hrn(xrn)[0] for xrn in xrns]

        # load all known registry names into a prefix tree and attempt to find
        # the longest matching prefix
        # create a dict where key is a registry hrn and its value is a list
        # of hrns at that registry (determined by the known prefix tree).  
        xrn_dict = {}
        registries = api.registries
        tree = prefixTree()
        registry_hrns = registries.keys()
        tree.load(registry_hrns)
        for xrn in xrns:
            registry_hrn = tree.best_match(urn_to_hrn(xrn)[0])
            if registry_hrn not in xrn_dict:
                xrn_dict[registry_hrn] = []
            xrn_dict[registry_hrn].append(xrn)

        records = []
        for registry_hrn in xrn_dict:
            # skip the hrn without a registry hrn
            # XX should we let the user know the authority is unknown?       
            if not registry_hrn:
                continue

            # if the best match (longest matching hrn) is not the local registry,
            # forward the request
            xrns = xrn_dict[registry_hrn]
            if registry_hrn != api.hrn:
                credential = api.getCredential()
                interface = api.registries[registry_hrn]
                server_proxy = api.server_proxy(interface, credential)
                # should propagate the details flag but that's not supported in the xmlrpc interface yet
                #peer_records = server_proxy.Resolve(xrns, credential,type, details=details)
                peer_records = server_proxy.Resolve(xrns, credential)
                # pass foreign records as-is
                # previous code used to read
                # records.extend([SfaRecord(dict=record).as_dict() for record in peer_records])
                # not sure why the records coming through xmlrpc had to be processed at all
                records.extend(peer_records)

        # try resolving the remaining unfound records at the local registry
        local_hrns = list ( set(hrns).difference([record['hrn'] for record in records]) )
        # 
        local_records = dbsession.query(RegRecord).filter(RegRecord.hrn.in_(local_hrns))
        if type:
            local_records = local_records.filter_by(type=type)
        local_records=local_records.all()

        for local_record in local_records:
            augment_with_sfa_builtins (local_record)

        logger.info("Resolve, (details=%s,type=%s) local_records=%s "%(details,type,local_records))
        local_dicts = [ record.__dict__ for record in local_records ]

        if details:
            # in details mode we get as much info as we can, which involves contacting the 
            # testbed for getting implementation details about the record
            self.driver.augment_records_with_testbed_info(local_dicts)
            # also we fill the 'url' field for known authorities
            # used to be in the driver code, sounds like a poorman thing though
            def solve_neighbour_url (record):
                if not record.type.startswith('authority'): return
                hrn=record.hrn
                for neighbour_dict in [ api.aggregates, api.registries ]:
                    if hrn in neighbour_dict:
                        record.url=neighbour_dict[hrn].get_url()
                        return
            for record in local_records: 
                solve_neighbour_url (record)

        # convert local record objects to dicts for xmlrpc
        # xxx somehow here calling dict(record) issues a weird error
        # however record.todict() seems to work fine
        # records.extend( [ dict(record) for record in local_records ] )
        records.extend( [ record.todict(exclude_types=[InstrumentedList]) for record in local_records ] )

        if not records:
            raise RecordNotFound(str(hrns))

        return records
Esempio n. 14
0
    def get_key_from_incoming_ip(self, api):
        dbsession = api.dbsession()
        # verify that the callers's ip address exist in the db and is an interface
        # for a node in the db
        (ip, port) = api.remote_addr
        interfaces = api.driver.shell.GetInterfaces({'ip': ip}, ['node_id'])
        if not interfaces:
            raise NonExistingRecord("no such ip %(ip)s" % locals())
        nodes = api.driver.shell.GetNodes([interfaces[0]['node_id']],
                                          ['node_id', 'hostname'])
        if not nodes:
            raise NonExistingRecord("no such node using ip %(ip)s" % locals())
        node = nodes[0]

        # look up the sfa record
        record = dbsession.query(RegRecord).filter_by(
            type='node', pointer=node['node_id']).first()
        if not record:
            raise RecordNotFound("node with pointer %s" % node['node_id'])

        # generate a new keypair and gid
        uuid = create_uuid()
        pkey = Keypair(create=True)
        urn = hrn_to_urn(record.hrn, record.type)
        gid_object = api.auth.hierarchy.create_gid(urn, uuid, pkey)
        gid = gid_object.save_to_string(save_parents=True)
        record.gid = gid

        # update the record
        dbsession.commit()

        # attempt the scp the key
        # and gid onto the node
        # this will only work for planetlab based components
        (kfd, key_filename) = tempfile.mkstemp()
        (gfd, gid_filename) = tempfile.mkstemp()
        pkey.save_to_file(key_filename)
        gid_object.save_to_file(gid_filename, save_parents=True)
        host = node['hostname']
        key_dest = "/etc/sfa/node.key"
        gid_dest = "/etc/sfa/node.gid"
        scp = "/usr/bin/scp"
        #identity = "/etc/planetlab/root_ssh_key.rsa"
        identity = "/etc/sfa/root_ssh_key"
        scp_options = " -i %(identity)s " % locals()
        scp_options += "-o StrictHostKeyChecking=no " % locals()
        scp_key_command="%(scp)s %(scp_options)s %(key_filename)s root@%(host)s:%(key_dest)s" %\
                         locals()
        scp_gid_command="%(scp)s %(scp_options)s %(gid_filename)s root@%(host)s:%(gid_dest)s" %\
                         locals()

        all_commands = [scp_key_command, scp_gid_command]

        for command in all_commands:
            (status, output) = commands.getstatusoutput(command)
            if status:
                raise Exception, output

        for filename in [key_filename, gid_filename]:
            os.unlink(filename)

        return 1
Esempio n. 15
0
    def Update(self, api, record_dict):
        dbsession = api.dbsession()
        assert ('type' in record_dict)
        new_record = make_record(dict=record_dict)
        (type, hrn) = (new_record.type, new_record.hrn)

        # make sure the record exists
        record = dbsession.query(RegRecord).filter_by(type=type,
                                                      hrn=hrn).first()
        if not record:
            raise RecordNotFound("hrn=%s, type=%s" % (hrn, type))
        record.just_updated()

        # Use the pointer from the existing record, not the one that the user
        # gave us. This prevents the user from inserting a forged pointer
        pointer = record.pointer

        # is there a change in keys ?
        new_key = None
        if type == 'user':
            if getattr(new_record, 'keys', None):
                new_key = new_record.keys
                if isinstance(new_key, types.ListType):
                    new_key = new_key[0]

        # take new_key into account
        if new_key:
            # update the openssl key and gid
            pkey = convert_public_key(new_key)
            uuid = create_uuid()
            urn = hrn_to_urn(hrn, type)
            gid_object = api.auth.hierarchy.create_gid(urn, uuid, pkey)
            gid = gid_object.save_to_string(save_parents=True)

        # xxx should do side effects from new_record to record
        # not too sure how to do that
        # not too big a deal with planetlab as the driver is authoritative, but...

        # update native relations
        if isinstance(record, RegSlice):
            researcher_hrns = getattr(new_record, 'researcher', None)
            if researcher_hrns is not None:
                record.update_researchers(researcher_hrns, dbsession)

        elif isinstance(record, RegAuthority):
            pi_hrns = getattr(new_record, 'pi', None)
            if pi_hrns is not None: record.update_pis(pi_hrns, dbsession)

        # update the PLC information that was specified with the record
        # xxx oddly enough, without this useless statement,
        # record.__dict__ as received by the driver seems to be off
        # anyway the driver should receive an object
        # (and then extract __dict__ itself if needed)
        print "DO NOT REMOVE ME before driver.update, record=%s" % record
        new_key_pointer = -1
        try:
            (pointer,
             new_key_pointer) = api.driver.update(record.__dict__,
                                                  new_record.__dict__, hrn,
                                                  new_key)
        except:
            pass
        if new_key and new_key_pointer:
            record.reg_keys = [RegKey(new_key, new_key_pointer)]
            record.gid = gid

        dbsession.commit()
        # update membership for researchers, pis, owners, operators
        self.update_driver_relations(api, record, new_record)

        return 1