Beispiel #1
0
 def save (self):
     try:
         outfile=file(self.filename,'w')
         pickle.dump(self.url2version,outfile)
         outfile.close()
     except:
         logger.log_exc ("Cannot save version cache into %s"%self.filename)
Beispiel #2
0
    def do_POST(self):
        """Handles the HTTPS POST request.

        It was copied out from SimpleXMLRPCServer.py and modified to shutdown 
        the socket cleanly.
        """
        try:
            peer_cert = Certificate()
            peer_cert.load_from_pyopenssl_x509(self.connection.get_peer_certificate())
            generic=Generic.the_flavour()
            self.api = generic.make_api (peer_cert = peer_cert, 
                                         interface = self.server.interface, 
                                         key_file = self.server.key_file, 
                                         cert_file = self.server.cert_file,
                                         cache = self.cache)
            #logger.info("SecureXMLRpcRequestHandler.do_POST:")
            #logger.info("interface=%s"%self.server.interface)
            #logger.info("key_file=%s"%self.server.key_file)
            #logger.info("api=%s"%self.api)
            #logger.info("server=%s"%self.server)
            #logger.info("handler=%s"%self)
            # get arguments
            request = self.rfile.read(int(self.headers["content-length"]))
            remote_addr = (remote_ip, remote_port) = self.connection.getpeername()
            self.api.remote_addr = remote_addr            
            response = self.api.handle(remote_addr, request, self.server.method_map)
        except Exception, fault:
            # This should only happen if the module is buggy
            # internal error, report as HTTP server error
            logger.log_exc("server.do_POST")
            response = self.api.prepare_response(fault)
Beispiel #3
0
 def delete_security_group(self, name):
     try:
         security_group = self.client.security_groups.find(name=name)
         if not security_group.name == 'default':
             self.client.security_groups.delete(security_group.id)
     except Exception, ex:
         logger.log_exc("Failed to delete security group")
Beispiel #4
0
 def save(self):
     try:
         outfile = file(self.filename, 'w')
         pickle.dump(self.url2version, outfile)
         outfile.close()
     except:
         logger.log_exc("Cannot save version cache into %s" % self.filename)
Beispiel #5
0
    def get_slice_and_slivers(self, slice_xrn, login=None):
        """
        Returns a dict of slivers keyed on the sliver's node_id
        """
        slivers = {}
        sfa_slice = None
        if not slice_xrn:
            return (sfa_slice, slivers)
        slice_urn = hrn_to_urn(slice_xrn, 'slice')
        slice_hrn, _ = urn_to_hrn(slice_xrn)
        slice_name = slice_hrn

        slices = self.driver.GetSlices(slice_filter= str(slice_name), \
                                                slice_filter_type = 'slice_hrn', login=login)
        
        logger.debug("Slabaggregate api \tget_slice_and_slivers \
                        sfa_slice %s \r\n slices %s self.driver.hrn %s" \
                        %(sfa_slice, slices, self.driver.hrn))
        if not slices:
            return (sfa_slice, slivers)
        #if isinstance(sfa_slice, list):
            #sfa_slice = slices[0]
        #else:
            #sfa_slice = slices

        # sort slivers by node id , if there is a job
        #and therfore, node allocated to this slice
        for sfa_slice in slices:
            try:
                node_ids_list =  sfa_slice['node_ids']  
            except KeyError:
                logger.log_exc("SLABAGGREGATE \t \
                                        get_slice_and_slivers KeyError ")
                continue
                                        
            for node in node_ids_list:
                sliver_xrn = Xrn(slice_urn, type='sliver', id=node)
                sliver_xrn.set_authority(self.driver.hrn)
                #node_id = self.driver.root_auth + '.' + node_id
                sliver = Sliver({'sliver_id':sliver_xrn.urn, 
                                'name': sfa_slice['hrn'],
                                'type': 'slab-node', 
                                'tags': []})
                
                slivers[node] = sliver
          
        
        #Add default sliver attribute :
        #connection information for senslab
        if get_authority (sfa_slice['hrn']) == self.driver.root_auth: 
            tmp = sfa_slice['hrn'].split('.')
            ldap_username = tmp[1].split('_')[0]
            vmaddr = 'ssh ' + ldap_username + '@grenoble.senslab.info'
            slivers['default_sliver'] =  {'vm': vmaddr , 'login': ldap_username}
            
        #TODO get_slice_and_slivers Find the login of the external user

        logger.debug("SLABAGGREGATE api get_slice_and_slivers  slivers %s "\
                                                             %(slivers))
        return (slices, slivers)
Beispiel #6
0
def convert_public_key(key):
    keyconvert_path = "/usr/bin/keyconvert.py"
    if not os.path.isfile(keyconvert_path):
        raise IOError, "Could not find keyconvert in %s" % keyconvert_path

    # we can only convert rsa keys
    if "ssh-dss" in key:
        return None

    (ssh_f, ssh_fn) = tempfile.mkstemp()
    ssl_fn = tempfile.mktemp()
    os.write(ssh_f, key)
    os.close(ssh_f)

    cmd = keyconvert_path + " " + ssh_fn + " " + ssl_fn
    os.system(cmd)

    # this check leaves the temporary file containing the public key so
    # that it can be expected to see why it failed.
    # TODO: for production, cleanup the temporary files
    if not os.path.exists(ssl_fn):
        return None

    k = Keypair()
    try:
        k.load_pubkey_from_file(ssl_fn)
    except:
        logger.log_exc("convert_public_key caught exception")
        k = None

    # remove the temporary files
    os.remove(ssh_fn)
    os.remove(ssl_fn)

    return k
Beispiel #7
0
 def nuke (self):
     model.drop_tables(self.engine)
     # so in this case it's like we haven't initialized the db at all
     try:
         migrate.drop_version_control (self.url, self.repository)
     except migrate.exceptions.DatabaseNotControlledError:
         logger.log_exc("Failed to drop version control")
Beispiel #8
0
def convert_public_key(key):
    keyconvert_path = "/usr/bin/keyconvert.py"
    if not os.path.isfile(keyconvert_path):
        raise IOError, "Could not find keyconvert in %s" % keyconvert_path

    # we can only convert rsa keys
    if "ssh-dss" in key:
        return None

    (ssh_f, ssh_fn) = tempfile.mkstemp()
    ssl_fn = tempfile.mktemp()
    os.write(ssh_f, key)
    os.close(ssh_f)

    cmd = keyconvert_path + " " + ssh_fn + " " + ssl_fn
    os.system(cmd)

    # this check leaves the temporary file containing the public key so
    # that it can be expected to see why it failed.
    # TODO: for production, cleanup the temporary files
    if not os.path.exists(ssl_fn):
        return None

    k = Keypair()
    try:
        k.load_pubkey_from_file(ssl_fn)
    except:
        logger.log_exc("convert_public_key caught exception")
        k = None

    # remove the temporary files
    os.remove(ssh_fn)
    os.remove(ssl_fn)

    return k
Beispiel #9
0
    def do_POST(self):
        """Handles the HTTPS POST request.

        It was copied out from SimpleXMLRPCServer.py and modified to shutdown 
        the socket cleanly.
        """
        try:
            peer_cert = Certificate()
            peer_cert.load_from_pyopenssl_x509(
                self.connection.get_peer_certificate())
            generic = Generic.the_flavour()
            self.api = generic.make_api(peer_cert=peer_cert,
                                        interface=self.server.interface,
                                        key_file=self.server.key_file,
                                        cert_file=self.server.cert_file,
                                        cache=self.cache)
            #logger.info("SecureXMLRpcRequestHandler.do_POST:")
            #logger.info("interface=%s"%self.server.interface)
            #logger.info("key_file=%s"%self.server.key_file)
            #logger.info("api=%s"%self.api)
            #logger.info("server=%s"%self.server)
            #logger.info("handler=%s"%self)
            # get arguments
            request = self.rfile.read(int(self.headers["content-length"]))
            remote_addr = (remote_ip,
                           remote_port) = self.connection.getpeername()
            self.api.remote_addr = remote_addr
            response = self.api.handle(remote_addr, request,
                                       self.server.method_map)
        except Exception, fault:
            # This should only happen if the module is buggy
            # internal error, report as HTTP server error
            logger.log_exc("server.do_POST")
            response = self.api.prepare_response(fault)
Beispiel #10
0
    def GETRequestToOARRestAPI(self, request, strval=None ,next_page=None, username = None ): 
        self.oarserver['uri'] = \
                            OARGETParser.OARrequests_uri_dict[request]['uri']
        #Get job details with username                   
        if 'owner' in OARGETParser.OARrequests_uri_dict[request] and username:
           self.oarserver['uri'] +=  OARGETParser.OARrequests_uri_dict[request]['owner'] + username
        headers = {}
        data = json.dumps({})
        logger.debug("OARrestapi \tGETRequestToOARRestAPI %s" %(request))
        if strval:
            self.oarserver['uri'] = self.oarserver['uri'].\
                                            replace("id",str(strval))
            
        if next_page:
            self.oarserver['uri'] += next_page
            
        if username:
            headers['X-REMOTE_IDENT'] = username 
            
        print>>sys.stderr, " \r\n \t    OARrestapi \tGETRequestToOARRestAPI %s" %( self.oarserver['uri'])
        logger.debug("OARrestapi: \t  GETRequestToOARRestAPI  \
                        self.oarserver['uri'] %s strval %s" \
                        %(self.oarserver['uri'], strval))
        try :  
            #seems that it does not work if we don't add this
            headers['content-length'] = '0' 

            conn = HTTPConnection(self.oarserver['ip'], \
                                                self.oarserver['port'])
            conn.request("GET", self.oarserver['uri'], data, headers)
            resp = ( conn.getresponse()).read()
            conn.close()
        except HTTPException, error :
            logger.log_exc("GET_OAR_SRVR : Problem with OAR server : %s " \
                                                                    %(error))
Beispiel #11
0
    def LdapModify(self, dn, old_attributes_dict, new_attributes_dict):
        """ Modifies a LDAP entry, replaces user's old attributes with
        the new ones given.

        :param dn: user's absolute name  in the LDAP hierarchy.
        :param old_attributes_dict: old user's attributes. Keys must match
            the ones used in the LDAP model.
        :param new_attributes_dict: new user's attributes. Keys must match
            the ones used in the LDAP model.
        :type dn: string
        :type old_attributes_dict: dict
        :type new_attributes_dict: dict
        :returns: dict bool True if Successful, bool False if not.
        :rtype: dict

        """

        ldif = modlist.modifyModlist(old_attributes_dict, new_attributes_dict)
        # Connect and bind/authenticate
        result = self.conn.connect()
        if (result['bool']):
            try:
                self.conn.ldapserv.modify_s(dn, ldif)
                self.conn.close()
                return {'bool': True}
            except ldap.LDAPError, error:
                logger.log_exc("LDAP LdapModify Error %s" % error)
                return {'bool': False}
Beispiel #12
0
    def ParseJobsIds(self):
        
        job_resources = ['wanted_resources', 'name', 'id', 'start_time', \
                        'state','owner','walltime','message']
        
        
        job_resources_full = ['launching_directory', 'links', \
            'resubmit_job_id', 'owner', 'events', 'message', \
            'scheduled_start', 'id', 'array_id',  'exit_code', \
            'properties', 'state','array_index', 'walltime', \
            'type', 'initial_request', 'stop_time', 'project',\
            'start_time',  'dependencies','api_timestamp','submission_time', \
            'reservation', 'stdout_file', 'types', 'cpuset_name', \
            'name',  'wanted_resources','queue','stderr_file','command']


        job_info = self.raw_json
        #logger.debug("OARESTAPI ParseJobsIds %s" %(self.raw_json))
        values = []
        try:
            for k in job_resources:
                values.append(job_info[k])
            return dict(zip(job_resources, values))
            
        except KeyError:
            logger.log_exc("ParseJobsIds KeyError ")
Beispiel #13
0
 def remove_rule_from_group(self,
                            group_name=None,
                            protocol='tcp',
                            cidr_ip='0.0.0.0/0',
                            port_range=None,
                            icmp_type_code=None,
                            source_group_name=None,
                            source_group_owner_id=None):
     try:
         from_port, to_port = self._validate_port_range(port_range)
         icmp_type = self._validate_icmp_type_code(icmp_type_code)
         if icmp_type:
             from_port, to_port = icmp_type[0], icmp_type[1]
         group = self.client.security_groups.find(name=group_name)
         filter = {
             'id': group.id,
             'from_port': from_port,
             'to_port': to_port,
             'cidr_ip': ip,
             'ip_protocol': protocol,
         }
         rule = self.client.security_group_rules.find(**filter)
         if rule:
             self.client.security_group_rules.delete(rule)
     except Exception, ex:
         logger.log_exc("Failed to remove rule from group %s" % group_name)
Beispiel #14
0
 def nuke(self):
     model.drop_tables(self.engine)
     # so in this case it's like we haven't initialized the db at all
     try:
         migrate.drop_version_control(self.url, self.repository)
     except migrate.exceptions.DatabaseNotControlledError:
         logger.log_exc("Failed to drop version control")
Beispiel #15
0
    def _process_walltime(duration):
        """ Calculates the walltime in seconds from the duration in H:M:S
            specified in the RSpec.

        """
        if duration:
            # Fixing the walltime by adding a few delays.
            # First put the walltime in seconds oarAdditionalDelay = 20;
            #  additional delay for /bin/sleep command to
            # take in account  prologue and epilogue scripts execution
            # int walltimeAdditionalDelay = 240;  additional delay
            #for prologue/epilogue execution = $SERVER_PROLOGUE_EPILOGUE_TIMEOUT
            #in oar.conf
            # Put the duration in seconds first
            #desired_walltime = duration * 60
            desired_walltime = duration
            total_walltime = desired_walltime + 240  #+4 min Update SA 23/10/12
            sleep_walltime = desired_walltime  # 0 sec added Update SA 23/10/12
            walltime = []
            #Put the walltime back in str form
            #First get the hours
            walltime.append(str(total_walltime / 3600))
            total_walltime = total_walltime - 3600 * int(walltime[0])
            #Get the remaining minutes
            walltime.append(str(total_walltime / 60))
            total_walltime = total_walltime - 60 * int(walltime[1])
            #Get the seconds
            walltime.append(str(total_walltime))

        else:
            logger.log_exc(" __process_walltime duration null")

        return walltime, sleep_walltime
Beispiel #16
0
    def _process_walltime(duration):
        """ Calculates the walltime in seconds from the duration in H:M:S
            specified in the RSpec.

        """
        if duration:
            # Fixing the walltime by adding a few delays.
            # First put the walltime in seconds oarAdditionalDelay = 20;
            #  additional delay for /bin/sleep command to
            # take in account  prologue and epilogue scripts execution
            # int walltimeAdditionalDelay = 240;  additional delay
            #for prologue/epilogue execution = $SERVER_PROLOGUE_EPILOGUE_TIMEOUT
            #in oar.conf
            # Put the duration in seconds first
            #desired_walltime = duration * 60
            desired_walltime = duration
            total_walltime = desired_walltime + 240 #+4 min Update SA 23/10/12
            sleep_walltime = desired_walltime  # 0 sec added Update SA 23/10/12
            walltime = []
            #Put the walltime back in str form
            #First get the hours
            walltime.append(str(total_walltime / 3600))
            total_walltime = total_walltime - 3600 * int(walltime[0])
            #Get the remaining minutes
            walltime.append(str(total_walltime / 60))
            total_walltime = total_walltime - 60 * int(walltime[1])
            #Get the seconds
            walltime.append(str(total_walltime))

        else:
            logger.log_exc(" __process_walltime duration null")

        return walltime, sleep_walltime
    def verify_slice_nodes(self, slice_urn, slice, rspec_nodes):
        slivers = {}
        for node in rspec_nodes:
            hostname = node.get('component_name')
            client_id = node.get('client_id')
            #client_id = node.get('component_id')

            component_id = node.get('component_id').strip()
            if hostname:
                hostname = hostname.strip()
            elif component_id:
                hostname = xrn_to_hostname(component_id)
            if hostname:
                slivers[hostname] = {'client_id': client_id, 'component_id': component_id}
        all_nodes = self.driver.shell.GetNodes()
        requested_slivers = []
        for node in all_nodes:
            if node['hostname'] in slivers.keys():
                requested_slivers.append(node['node_id'])
	

        if 'node_ids' not in slice.keys():
            slice['node_ids']=[] 
        nodes = self.driver.shell.GetNodes({'node_ids': slice['node_ids']})
        current_slivers = [node['node_id'] for node in nodes]

	
        # remove nodes not in rspec
        deleted_nodes = list(set(current_slivers).difference(requested_slivers))

        # add nodes from rspec
        added_nodes = list(set(requested_slivers).difference(current_slivers))        


        try:
            self.driver.shell.AddSliceToNodes({'slice_id': slice['slice_id'], 'node_ids': added_nodes})
            self.driver.shell.DeleteSliceFromNodes({'slice_id': slice['slice_id'], 'node_ids': deleted_nodes})

        except: 
            logger.log_exc('Failed to add/remove slice from nodes')

	
        slices = self.driver.shell.GetSlices({'slice_name': slice['slice_name']})
        
	resulting_nodes = self.driver.shell.GetNodes({'node_ids': slices[0]['node_ids']})


        # update sliver allocations
        for node in resulting_nodes:
            client_id = slivers[node['hostname']]['client_id']
            component_id = slivers[node['hostname']]['component_id']
            sliver_hrn = '%s.%s-%s' % (self.driver.hrn, slice['slice_id'], node['node_id'])
            sliver_id = Xrn(sliver_hrn, type='sliver').urn
            record = SliverAllocation(sliver_id=sliver_id, client_id=client_id,
                                      component_id=component_id,
                                      slice_urn = slice_urn,
                                      allocation_state='geni_allocated')
            record.sync(self.driver.api.dbsession())
        return resulting_nodes
Beispiel #18
0
def merge_rspecs(rspecs):
    """
    Merge merge a list of RSpecs into 1 RSpec, and return the result.
    rspecs must be a valid RSpec string or list of RSpec strings.
    """
    if not rspecs or not isinstance(rspecs, list):
        return rspecs

    # ugly hack to avoid sending the same info twice, when the call graph has dags
    known_networks={}
    def register_network (network):
        try:
            known_networks[network.get('name')]=True
        except:
            logger.error("merge_rspecs: cannot register network with no name in rspec")
            pass
    def is_registered_network (network):
        try:
            return network.get('name') in known_networks
        except:
            logger.error("merge_rspecs: cannot retrieve network with no name in rspec")
            return False

    # the resulting tree
    rspec = None
    for input_rspec in rspecs:
        # ignore empty strings as returned with used call_ids
        if not input_rspec: continue
        try:
            tree = etree.parse(StringIO(input_rspec))
        except etree.XMLSyntaxError:
            # consider failing silently here
            logger.log_exc("merge_rspecs, parse error")
            message = str(sys.exc_info()[1]) + ' with ' + input_rspec
            raise InvalidRSpec(message)

        root = tree.getroot()
        if not root.get("type") in ["SFA"]:
            logger.error("merge_rspecs: unexpected type for rspec root, %s"%root.get('type'))
            continue
        if rspec == None:
            # we scan the first input, register all networks
            # in addition we remove duplicates - needed until everyone runs 1.0-10
            rspec = root
            for network in root.iterfind("./network"):
                if not is_registered_network(network):
                    register_network(network)
                else:
                    # duplicate in the first input - trash it
                    root.remove(network)
        else:
            for network in root.iterfind("./network"):
                if not is_registered_network(network):
                    rspec.append(deepcopy(network))
                    register_network(network)
            for request in root.iterfind("./request"):
                rspec.append(deepcopy(request))
    return etree.tostring(rspec, xml_declaration=True, pretty_print=True)
Beispiel #19
0
    def run_instances(self, instance_name, tenant_name, rspec, key_name, pubkeys):
        #logger.debug('Reserving an instance: image: %s, flavor: ' \
        #            '%s, key: %s, name: %s' % \
        #            (image_id, flavor_id, key_name, slicename))

        # make sure a tenant exists for this slice
        tenant = self.create_tenant(tenant_name)  

        # add the sfa admin user to this tenant and update our nova client connection
        # to use these credentials for the rest of this session. This emsures that the instances
        # we create will be assigned to the correct tenant.
        sfa_admin_user = self.driver.shell.auth_manager.users.find(name=self.driver.shell.auth_manager.opts['OS_USERNAME'])
        user_role = self.driver.shell.auth_manager.roles.find(name='user')
        admin_role = self.driver.shell.auth_manager.roles.find(name='admin')
        self.driver.shell.auth_manager.roles.add_user_role(sfa_admin_user, admin_role, tenant)
        self.driver.shell.auth_manager.roles.add_user_role(sfa_admin_user, user_role, tenant)
        self.driver.shell.nova_manager.connect(tenant=tenant.name)  

        authorized_keys = "\n".join(pubkeys)
        files = {'/root/.ssh/authorized_keys': authorized_keys}
        rspec = RSpec(rspec)
        requested_instances = defaultdict(list)
        
        # iterate over clouds/zones/nodes
        created_instances = []
        for node in rspec.version.get_nodes_with_slivers():
            instances = node.get('slivers', [])
            if not instances:
                continue
            for instance in instances:
                try: 
                    metadata = {}
                    flavor_id = self.driver.shell.nova_manager.flavors.find(name=instance['name'])
                    image = instance.get('disk_image')
                    if image and isinstance(image, list):
                        image = image[0]
                    else:
                        raise InvalidRSpec("Must specify a disk_image for each VM")
                    image_id = self.driver.shell.nova_manager.images.find(name=image['name'])
                    fw_rules = instance.get('fw_rules', [])
                    group_name = self.create_security_group(instance_name, fw_rules)
                    metadata['security_groups'] = group_name
                    if node.get('component_id'):
                        metadata['component_id'] = node['component_id']
                    if node.get('client_id'):
                        metadata['client_id'] = node['client_id']
                    server = self.driver.shell.nova_manager.servers.create(flavor=flavor_id,
                                                            image=image_id,
                                                            key_name = key_name,
                                                            security_groups = [group_name],
                                                            files=files,
                                                            meta=metadata, 
                                                            name=instance_name)
                    created_instances.append(server)
                    
                except Exception, err:    
                    logger.log_exc(err)                                
Beispiel #20
0
    def run_instances(self, instance_name, tenant_name, rspec, key_name, pubkeys):
        #logger.debug('Reserving an instance: image: %s, flavor: ' \
        #            '%s, key: %s, name: %s' % \
        #            (image_id, flavor_id, key_name, slicename))

        # make sure a tenant exists for this slice
        tenant = self.create_tenant(tenant_name)  

        # add the sfa admin user to this tenant and update our nova client connection
        # to use these credentials for the rest of this session. This emsures that the instances
        # we create will be assigned to the correct tenant.
        sfa_admin_user = self.driver.shell.auth_manager.users.find(name=self.driver.shell.auth_manager.opts['OS_USERNAME'])
        user_role = self.driver.shell.auth_manager.roles.find(name='user')
        admin_role = self.driver.shell.auth_manager.roles.find(name='admin')
        self.driver.shell.auth_manager.roles.add_user_role(sfa_admin_user, admin_role, tenant)
        self.driver.shell.auth_manager.roles.add_user_role(sfa_admin_user, user_role, tenant)
        self.driver.shell.nova_manager.connect(tenant=tenant.name)  

        authorized_keys = "\n".join(pubkeys)
        files = {'/root/.ssh/authorized_keys': authorized_keys}
        rspec = RSpec(rspec)
        requested_instances = defaultdict(list)
        
        # iterate over clouds/zones/nodes
        slivers = []
        for node in rspec.version.get_nodes_with_slivers():
            instances = node.get('slivers', [])
            if not instances:
                continue
            for instance in instances:
                try: 
                    metadata = {}
                    flavor_id = self.driver.shell.nova_manager.flavors.find(name=instance['name'])
                    image = instance.get('disk_image')
                    if image and isinstance(image, list):
                        image = image[0]
                    else:
                        raise InvalidRSpec("Must specify a disk_image for each VM")
                    image_id = self.driver.shell.nova_manager.images.find(name=image['name'])
                    fw_rules = instance.get('fw_rules', [])
                    group_name = self.create_security_group(instance_name, fw_rules)
                    metadata['security_groups'] = group_name
                    if node.get('component_id'):
                        metadata['component_id'] = node['component_id']
                    if node.get('client_id'):
                        metadata['client_id'] = node['client_id'] 
                    server = self.driver.shell.nova_manager.servers.create(
                                                            flavor=flavor_id,
                                                            image=image_id,
                                                            key_name = key_name,
                                                            security_groups = [group_name],
                                                            files=files,
                                                            meta=metadata, 
                                                            name=instance_name)
                    slivers.append(server)
                except Exception, err:    
                    logger.log_exc(err)                                
Beispiel #21
0
    def LdapSearch(self, req_ldap=None, expected_fields=None):
        """
        Used to search directly in LDAP, by using ldap filters and return
        fields. When req_ldap is None, returns all the entries in the LDAP.

        :param req_ldap: ldap style request, with appropriate filters,
             example: (cn=*).
        :param expected_fields: Fields in the user ldap entry that has to be
            returned. If None is provided, will return 'mail', 'givenName',
            'sn', 'uid', 'sshPublicKey', 'shadowExpire'.
        :type req_ldap: string
        :type expected_fields: list

        .. seealso:: make_ldap_filters_from_record for req_ldap format.

        """
        result = self.conn.connect(bind=False)
        if (result['bool']):

            return_fields_list = []
            if expected_fields is None:
                return_fields_list = ['mail', 'givenName', 'sn', 'uid',
                                      'sshPublicKey', 'shadowExpire']
            else:
                return_fields_list = expected_fields
            #No specifc request specified, get the whole LDAP
            if req_ldap is None:
                req_ldap = '(cn=*)'

            logger.debug("LDAP.PY \t LdapSearch  req_ldap %s \
                                    return_fields_list %s" \
                                    %(req_ldap, return_fields_list))

            try:
                msg_id = self.conn.ldapserv.search(
                    self.baseDN, ldap.SCOPE_SUBTREE,
                    req_ldap, return_fields_list)
                #Get all the results matching the search from ldap in one
                #shot (1 value)
                result_type, result_data = \
                    self.conn.ldapserv.result(msg_id, 1)

                self.conn.close()

                logger.debug("LDAP.PY \t LdapSearch  result_data %s"
                             % (result_data))

                return result_data

            except ldap.LDAPError, error:
                logger.log_exc("LDAP LdapSearch Error %s" % error)
                return []

            else:
                logger.error("LDAP.PY \t Connection Failed")
                return
Beispiel #22
0
 def _Provision(aggregate, server, xrn, credential, options):
     tStart = time.time()
     try:
         # Need to call GetVersion at an aggregate to determine the supported
         # rspec type/format beofre calling CreateSliver at an Aggregate.
         server_version = api.get_cached_server_version(server)
         result = server.Provision(xrn, credential, options)
         return {"aggregate": aggregate, "result": result, "elapsed": time.time()-tStart, "status": "success"}
     except:
         logger.log_exc('Something wrong in _Allocate with URL %s'%server.url)
         return {"aggregate": aggregate, "elapsed": time.time()-tStart, "status": "exception", "exc_info": sys.exc_info()}
Beispiel #23
0
    def LaunchExperimentOnOAR(self, added_nodes, slice_name, \
                        lease_start_time, lease_duration, slice_user=None):

        """
        Create a job request structure based on the information provided
        and post the job on OAR.
        :param added_nodes: list of nodes that belong to the described lease.
        :param slice_name: the slice hrn associated to the lease.
        :param lease_start_time: timestamp of the lease startting time.
        :param lease_duration: lease durationin minutes

        """
        lease_dict = {}
        lease_dict['lease_start_time'] = lease_start_time
        lease_dict['lease_duration'] = lease_duration
        lease_dict['added_nodes'] = added_nodes
        lease_dict['slice_name'] = slice_name
        lease_dict['slice_user'] = slice_user
        lease_dict['grain'] = self.GetLeaseGranularity()
        # I don't know why the SFATIME_FORMAT has changed...
        # from sfa.util.sfatime import SFATIME_FORMAT
        # Let's use a fixed format %Y-%m-%d %H:%M:%S
        #lease_dict['time_format'] = self.time_format
        lease_dict['time_format'] = '%Y-%m-%d %H:%M:%S'


        logger.debug("IOTLAB_API.PY \tLaunchExperimentOnOAR slice_user %s\
                             \r\n "  %(slice_user))
        #Create the request for OAR
        reqdict = self._create_job_structure_request_for_OAR(lease_dict)
         # first step : start the OAR job and update the job
        logger.debug("IOTLAB_API.PY \tLaunchExperimentOnOAR reqdict %s\
                             \r\n "  %(reqdict))

        answer = self.oar.POSTRequestToOARRestAPI('POST_job', \
                                                reqdict, slice_user)
        logger.debug("IOTLAB_API \tLaunchExperimentOnOAR jobid  %s " %(answer))
        try:
            jobid = answer['id']
        except KeyError:
            logger.log_exc("IOTLAB_API \tLaunchExperimentOnOAR \
                                Impossible to create job  %s "  %(answer))
            return None




        if jobid :
            logger.debug("IOTLAB_API \tLaunchExperimentOnOAR jobid %s \
                    added_nodes %s slice_user %s" %(jobid, added_nodes, \
                                                            slice_user))


        return jobid
Beispiel #24
0
    def verify_slice_leases(self, slice, rspec_requested_leases, peer):

        leases = self.driver.shell.GetLeases({'name':slice['name'], 'clip':int(time.time())}, ['lease_id','name', 'hostname', 't_from', 't_until'])
        grain = self.driver.shell.GetLeaseGranularity()

        requested_leases = []
        for lease in rspec_requested_leases:
             requested_lease = {}
             slice_name = hrn_to_pl_slicename(lease['slice_id'])
             if slice_name != slice['name']:
                 continue
             elif Xrn(lease['component_id']).get_authority_urn().split(':')[0] != self.driver.hrn:
                 continue

             hostname = xrn_to_hostname(lease['component_id'])
             # fill the requested node with nitos ids
             requested_lease['name'] = slice['name']
             requested_lease['hostname'] = hostname
             requested_lease['t_from'] = int(lease['start_time'])
             requested_lease['t_until'] = int(lease['duration']) * grain + int(lease['start_time'])
             requested_leases.append(requested_lease)



        # prepare actual slice leases by lease_id  
        leases_by_id = {}
        for lease in leases:
             leases_by_id[lease['lease_id']] = {'name': lease['name'], 'hostname': lease['hostname'], \
                                                't_from': lease['t_from'], 't_until': lease['t_until']}
        
        added_leases = []
        kept_leases_id = []
        deleted_leases_id = []
        for lease_id in leases_by_id:
             if leases_by_id[lease_id] not in requested_leases:
                 deleted_leases_id.append(lease_id)
             else:
                 kept_leases_id.append(lease_id)
                 requested_leases.remove(leases_by_id[lease_id])
        added_leases = requested_leases
   

        try:
            if peer:
                self.driver.shell.UnBindObjectFromPeer('slice', slice['slice_id'], peer['shortname'])
            self.driver.shell.DeleteLeases(deleted_leases_id)
            for lease in added_leases:
                self.driver.shell.AddLeases(lease['hostname'], slice['name'], lease['t_from'], lease['t_until'])

        except: 
            logger.log_exc('Failed to add/remove slice leases')

        return leases
Beispiel #25
0
 def _Renew(aggregate, server, xrn, creds, expiration_time, options):
     try:
         result=server.Renew(xrn, creds, expiration_time, options)
         if type(result)!=dict:
             result = {'code': {'geni_code': 0}, 'value': result}
         result['aggregate'] = aggregate
         return result
     except:
         logger.log_exc('Something wrong in _Renew with URL %s'%server.url)
         return {'aggregate': aggregate, 'exc_info': traceback.format_exc(),
                 'code': {'geni_code': -1},
                 'value': False, 'output': ""}
Beispiel #26
0
    def LdapGenerateUniqueLogin(self, record):
        """

        Generate login for adding a new user in LDAP Directory
        (four characters minimum length). Get proper last name and
        first name so that the user's login can be generated.

        :param record: Record must contain first_name and last_name.
        :type record: dict
        :returns: the generated login for the user described with record if the
            login generation is successful, None if it fails.
        :rtype: string or None

        """
        #For compatibility with other ldap func
        if 'mail' in record and 'email' not in record:
            record['email'] = record['mail']

        lower_first_name, lower_last_name =  \
            self.login_pwd.get_user_firstname_lastname(record)

        index, login = self.login_pwd.choose_sets_chars_for_login(
            lower_first_name, lower_last_name)

        login_filter = '(uid=' + login + ')'
        get_attrs = ['uid']
        try:
            #Check if login already in use

            while (len(self.LdapSearch(login_filter, get_attrs)) is not 0):

                index += 1
                if index >= 9:
                    logger.error("LoginException : Generation login error \
                                    with minimum four characters")
                else:
                    try:
                        login = \
                            lower_first_name[0:index] + \
                            lower_last_name[0:
                                            self.login_pwd.login_max_length
                                            - index]
                        login_filter = '(uid=' + login + ')'
                    except KeyError:
                        print "lower_first_name - lower_last_name too short"

            logger.debug("LDAP.API \t LdapGenerateUniqueLogin login %s"
                         % (login))
            return login

        except ldap.LDAPError, error:
            logger.log_exc("LDAP LdapGenerateUniqueLogin Error %s" % (error))
            return None
Beispiel #27
0
    def verify_slice_leases_nodes(self, slice, rspec_requested_nodes):
        nodes = self.driver.shell.getNodes({}, [])
  
        requested_nodes = []
        for node in rspec_requested_nodes:
             requested_node = {}
             nitos_nodes = []
             nitos_nodes.extend(nodes)
             slice_name = hrn_to_nitos_slicename(node['slice_id'])
             if slice_name != slice['slice_name']:
                 continue
             hostname = xrn_to_hostname(node['component_id'])
             nitos_node = self.driver.filter_nitos_results(nitos_nodes, {'hostname': hostname})
             if not nitos_node:
                 continue
             nitos_node = nitos_node[0]
             # fill the requested node with nitos ids
             requested_node['slice_id'] = slice['slice_id']
             requested_node['node_id'] = nitos_node['node_id']
             requested_node['start_time'] = node['start_time']
             requested_node['end_time'] = str(int(node['duration']) * int(self.driver.testbedInfo['grain']) + int(node['start_time']))
             requested_nodes.append(requested_node)

        # get actual nodes reservation data for the slice
        reserved_nodes = self.driver.filter_nitos_results(self.driver.shell.getReservedNodes({}, []), {'slice_id': slice['slice_id']})
         
        reserved_nodes_by_id = {}
        for node in reserved_nodes:
             reserved_nodes_by_id[node['reservation_id']] = {'slice_id': node['slice_id'], \
                                      'node_id': node['node_id'], 'start_time': node['start_time'], \
                                      'end_time': node['end_time']}

        added_nodes = []
        kept_nodes_id = []
        deleted_nodes_id = []
        for reservation_id in reserved_nodes_by_id:
             if reserved_nodes_by_id[reservation_id] not in requested_nodes:
                 deleted_nodes_id.append(reservation_id)
             else:
                 kept_nodes_id.append(reservation_id)
                 requested_nodes.remove(reserved_nodes_by_id[reservation_id])
        added_nodes = requested_nodes


        try:
            deleted=self.driver.shell.releaseNodes({'reservation_ids': deleted_nodes_id})
            for node in added_nodes:
                added=self.driver.shell.reserveNodes({'slice_id': slice['slice_id'], 'start_time': node['start_time'], 'end_time': node['end_time'], 'nodes': [node['node_id']]})

        except:
            logger.log_exc('Failed to add/remove slice leases nodes')

        return added_nodes
Beispiel #28
0
    def verify_slice_nodes(self, slice_urn, slice, rspec_nodes):

        slivers = {}
        for node in rspec_nodes:
            hostname = node.get('component_name')
            client_id = node.get('client_id')
            component_id = node.get('component_id').strip()
            if hostname:
                hostname = hostname.strip()
            elif component_id:
                hostname = xrn_to_hostname(component_id)
            if hostname:
                slivers[hostname] = {
                    'client_id': client_id,
                    'component_id': component_id
                }

        nodes = self.driver.shell.GetNodes(
            slice['node_ids'], ['node_id', 'hostname', 'interface_ids'])
        current_slivers = [node['hostname'] for node in nodes]

        # remove nodes not in rspec
        deleted_nodes = list(set(current_slivers).difference(slivers.keys()))

        # add nodes from rspec
        added_nodes = list(set(slivers.keys()).difference(current_slivers))

        try:
            self.driver.shell.AddSliceToNodes(slice['name'], added_nodes)
            self.driver.shell.DeleteSliceFromNodes(slice['name'],
                                                   deleted_nodes)

        except:
            logger.log_exc('Failed to add/remove slice from nodes')

        slices = self.driver.shell.GetSlices(slice['name'], ['node_ids'])
        resulting_nodes = self.driver.shell.GetNodes(slices[0]['node_ids'])

        # update sliver allocations
        for node in resulting_nodes:
            client_id = slivers[node['hostname']]['client_id']
            component_id = slivers[node['hostname']]['component_id']
            sliver_hrn = '%s.%s-%s' % (self.driver.hrn, slice['slice_id'],
                                       node['node_id'])
            sliver_id = Xrn(sliver_hrn, type='sliver').urn
            record = SliverAllocation(sliver_id=sliver_id,
                                      client_id=client_id,
                                      component_id=component_id,
                                      slice_urn=slice_urn,
                                      allocation_state='geni_allocated')
            record.sync(self.driver.api.dbsession())
        return resulting_nodes
Beispiel #29
0
 def the_flavour (flavour=None, config=None):
     if config is None: config=Config()
     if flavour is None: flavour=config.SFA_GENERIC_FLAVOUR
     flavour = flavour.lower()
     #mixed = flavour.capitalize()
     module_path="sfa.generic.%s"%flavour
     classname="%s"%flavour
     logger.debug("Generic.the_flavour with flavour=%s"%flavour)
     try:
         module = __import__ (module_path, globals(), locals(), [classname])
         return getattr(module, classname)(flavour,config)
     except:
         logger.log_exc("Cannot locate generic instance with flavour=%s"%flavour)
Beispiel #30
0
    def LdapAddUser(self, record) :
        """Add SFA user to LDAP if it is not in LDAP  yet.

        :param record: dictionnary with the user's data.
        :returns: a dictionary with the status (Fail= False, Success= True)
            and the uid of the newly added user if successful, or the error
            message it is not. Dict has keys bool and message in case of
            failure, and bool uid in case of success.
        :rtype: dict

        .. seealso:: make_ldap_filters_from_record

        """
        logger.debug(" \r\n \t LDAP LdapAddUser \r\n\r\n ================\r\n ")
        user_ldap_attrs = self.make_ldap_attributes_from_record(record)

        #Check if user already in LDAP wih email, first name and last name
        filter_by = self.make_ldap_filters_from_record(user_ldap_attrs)
        user_exist = self.LdapSearch(filter_by)
        if user_exist:
            logger.warning(" \r\n \t LDAP LdapAddUser user %s %s \
                        already exists" % (user_ldap_attrs['sn'],
                           user_ldap_attrs['mail']))
            return {'bool': False}

        #Bind to the server
        result = self.conn.connect()

        if(result['bool']):

            # A dict to help build the "body" of the object
            logger.debug(" \r\n \t LDAP LdapAddUser attrs %s "
                         % user_ldap_attrs)

            # The dn of our new entry/object
            dn = 'uid=' + user_ldap_attrs['uid'] + "," + self.baseDN

            try:
                ldif = modlist.addModlist(user_ldap_attrs)
                logger.debug("LDAPapi.py add attrs %s \r\n  ldif %s"
                             % (user_ldap_attrs, ldif))
                self.conn.ldapserv.add_s(dn, ldif)

                logger.info("Adding user %s login %s in LDAP"
                            % (user_ldap_attrs['cn'], user_ldap_attrs['uid']))
            except ldap.LDAPError, error:
                logger.log_exc("LDAP Add Error %s" % error)
                return {'bool': False, 'message': error}

            self.conn.close()
            return {'bool': True, 'uid': user_ldap_attrs['uid']}
Beispiel #31
0
    def GetNodes(self, node_filter_dict=None, return_fields_list=None):
        """

        Make a list of iotlab nodes and their properties from information
            given by OAR. Search for specific nodes if some filters are
            specified. Nodes properties returned if no return_fields_list given:
            'hrn','archi','mobile','hostname','site','boot_state','node_id',
            'radio','posx','posy','oar_id','posz'.

        :param node_filter_dict: dictionnary of lists with node properties. For
            instance, if you want to look for a specific node with its hrn,
            the node_filter_dict should be {'hrn': [hrn_of_the_node]}
        :type node_filter_dict: dict
        :param return_fields_list: list of specific fields the user wants to be
            returned.
        :type return_fields_list: list
        :returns: list of dictionaries with node properties
        :rtype: list

        """
        node_dict_by_id = self.oar.parser.SendRequest("GET_resources_full")
        node_dict_list = node_dict_by_id.values()
        logger.debug (" IOTLAB_API GetNodes  node_filter_dict %s \
            return_fields_list %s " % (node_filter_dict, return_fields_list))
        #No  filtering needed return the list directly
        if not (node_filter_dict or return_fields_list):
            return node_dict_list

        return_node_list = []
        if node_filter_dict:
            for filter_key in node_filter_dict:
                try:
                    #Filter the node_dict_list by each value contained in the
                    #list node_filter_dict[filter_key]
                    for value in node_filter_dict[filter_key]:
                        for node in node_dict_list:
                            if node[filter_key] == value:
                                if return_fields_list:
                                    tmp = {}
                                    for k in return_fields_list:
                                        tmp[k] = node[k]
                                    return_node_list.append(tmp)
                                else:
                                    return_node_list.append(node)
                except KeyError:
                    logger.log_exc("GetNodes KeyError")
                    return


        return return_node_list
Beispiel #32
0
 def the_flavour(flavour=None, config=None):
     if config is None: config = Config()
     if flavour is None: flavour = config.SFA_GENERIC_FLAVOUR
     flavour = flavour.lower()
     #mixed = flavour.capitalize()
     module_path = "sfa.generic.%s" % flavour
     classname = "%s" % flavour
     logger.debug("Generic.the_flavour with flavour=%s" % flavour)
     try:
         module = __import__(module_path, globals(), locals(), [classname])
         return getattr(module, classname)(flavour, config)
     except:
         logger.log_exc("Cannot locate generic instance with flavour=%s" %
                        flavour)
Beispiel #33
0
 def LdapModify(self, dn, old_attributes_dict, new_attributes_dict): 
     """ Modifies a LDAP entry """
      
     ldif = modlist.modifyModlist(old_attributes_dict,new_attributes_dict)
     # Connect and bind/authenticate    
     result = self.conn.connect() 
     if (result['bool']): 
         try:
             self.conn.ldapserv.modify_s(dn,ldif)
             self.conn.close()
             return {'bool' : True }
         except ldap.LDAPError, error:
             logger.log_exc("LDAP LdapModify Error %s" %error)
             return {'bool' : False }
Beispiel #34
0
 def __init__(self, manager, interface, config):
     if isinstance (manager, ModuleType):
         # old-fashioned module implementation
         self.manager = manager
     elif isinstance (manager, ClassType):
         # create an instance; we don't pass the api in argument as it is passed 
         # to the actual method calls anyway
         self.manager = manager(config)
     else:
         # that's what happens when there's something wrong with the db
         # or any bad stuff of that kind at startup time
         logger.log_exc("Failed to create a manager, startup sequence is broken")
         raise SfaAPIError,"Argument to ManagerWrapper must be a module or class"
     self.interface = interface
Beispiel #35
0
    def verify_slice_leases_channels(self, slice, rspec_requested_channels):
        channels = self.driver.shell.getChannels({}, [])

        requested_channels = []
        for channel in rspec_requested_channels:
             requested_channel = {}
             nitos_channels = []
             nitos_channels.extend(channels)
             slice_name = hrn_to_nitos_slicename(channel['slice_id'])
             if slice_name != slice['slice_name']:
                 continue
             channel_num = xrn_to_channel(channel['component_id'])
             nitos_channel = self.driver.filter_nitos_results(nitos_channels, {'channel': channel_num})[0]
             # fill the requested channel with nitos ids
             requested_channel['slice_id'] = slice['slice_id']
             requested_channel['channel_id'] = nitos_channel['channel_id']
             requested_channel['start_time'] = channel['start_time']
             requested_channel['end_time'] = str(int(channel['duration']) * int(self.driver.testbedInfo['grain']) + int(channel['start_time']))
             requested_channels.append(requested_channel)

        # get actual channel reservation data for the slice
        reserved_channels = self.driver.filter_nitos_results(self.driver.shell.getReservedChannels(), {'slice_id': slice['slice_id']})
        
        reserved_channels_by_id = {}
        for channel in reserved_channels:
             reserved_channels_by_id[channel['reservation_id']] = {'slice_id': channel['slice_id'], \
                                      'channel_id': channel['channel_id'], 'start_time': channel['start_time'], \
                                      'end_time': channel['end_time']}

        added_channels = []
        kept_channels_id = []
        deleted_channels_id = []
        for reservation_id in reserved_channels_by_id:
             if reserved_channels_by_id[reservation_id] not in requested_channels:
                 deleted_channels_id.append(reservation_id)
             else:
                 kept_channels_id.append(reservation_id)
                 requested_channels.remove(reserved_channels_by_id[reservation_id])
        added_channels = requested_channels

        
        try:
            deleted=self.driver.shell.releaseChannels({'reservation_ids': deleted_channels_id})
            for channel in added_channels:
                added=self.driver.shell.reserveChannels({'slice_id': slice['slice_id'], 'start_time': channel['start_time'], 'end_time': channel['end_time'], 'channels': [channel['channel_id']]})

        except:
            logger.log_exc('Failed to add/remove slice leases channels')
         
        return added_channels
Beispiel #36
0
    def GetNodes(self, node_filter_dict=None, return_fields_list=None):
        """

        Make a list of iotlab nodes and their properties from information
            given by OAR. Search for specific nodes if some filters are
            specified. Nodes properties returned if no return_fields_list given:
            'hrn','archi','mobile','hostname','site','boot_state','node_id',
            'radio','posx','posy','oar_id','posz'.

        :param node_filter_dict: dictionnary of lists with node properties. For
            instance, if you want to look for a specific node with its hrn,
            the node_filter_dict should be {'hrn': [hrn_of_the_node]}
        :type node_filter_dict: dict
        :param return_fields_list: list of specific fields the user wants to be
            returned.
        :type return_fields_list: list
        :returns: list of dictionaries with node properties
        :rtype: list

        """
        node_dict_by_id = self.oar.parser.SendRequest("GET_resources_full")
        node_dict_list = node_dict_by_id.values()
        logger.debug(" IOTLAB_API GetNodes  node_filter_dict %s \
            return_fields_list %s " % (node_filter_dict, return_fields_list))
        #No  filtering needed return the list directly
        if not (node_filter_dict or return_fields_list):
            return node_dict_list

        return_node_list = []
        if node_filter_dict:
            for filter_key in node_filter_dict:
                try:
                    #Filter the node_dict_list by each value contained in the
                    #list node_filter_dict[filter_key]
                    for value in node_filter_dict[filter_key]:
                        for node in node_dict_list:
                            if node[filter_key] == value:
                                if return_fields_list:
                                    tmp = {}
                                    for k in return_fields_list:
                                        tmp[k] = node[k]
                                    return_node_list.append(tmp)
                                else:
                                    return_node_list.append(node)
                except KeyError:
                    logger.log_exc("GetNodes KeyError")
                    return

        return return_node_list
Beispiel #37
0
 def exists(self, tablename):
     """
     Checks if the table specified as tablename exists.
 
     """
    
     try:
         metadata = MetaData (bind=self.slab_engine)
         table = Table (tablename, metadata, autoload=True)
         return True
     
     except NoSuchTableError:
         logger.log_exc("SLABPOSTGRES tablename %s does not exists" \
                         %(tablename))
         return False
Beispiel #38
0
    def add_rule_to_group(self, group_name=None, protocol='tcp', cidr_ip='0.0.0.0/0',
                          port_range=None, icmp_type_code=None,
                          source_group_name=None, source_group_owner_id=None):

        try:
            from_port, to_port = self._validate_port_range(port_range)
            icmp_type = self._validate_icmp_type_code(icmp_type_code)
            if icmp_type and icmp_type[0] and icmp_type[1]:
                from_port, to_port = icmp_type[0], icmp_type[1]

            group = self.client.security_groups.find(name=group_name)
            self.client.security_group_rules.create(group.id, \
                                protocol, from_port, to_port,cidr_ip)
        except Exception, ex:
            logger.log_exc("Failed to add rule to group %s" % group_name)
Beispiel #39
0
 def LdapDelete(self, person_dn):
     """
     Deletes a person in LDAP. Uses the dn of the user.
     """
     #Connect and bind   
     result =  self.conn.connect()
     if(result['bool']):
         try:
             self.conn.ldapserv.delete_s(person_dn)
             self.conn.close()
             return {'bool': True}
         
         except ldap.LDAPError, error:
             logger.log_exc("LDAP Delete Error %s" %error)
             return {'bool': False}
Beispiel #40
0
 def __init__(self, manager, interface, config):
     if isinstance(manager, ModuleType):
         # old-fashioned module implementation
         self.manager = manager
     elif isinstance(manager, ClassType):
         # create an instance; we don't pass the api in argument as it is passed
         # to the actual method calls anyway
         self.manager = manager(config)
     else:
         # that's what happens when there's something wrong with the db
         # or any bad stuff of that kind at startup time
         logger.log_exc(
             "Failed to create a manager, startup sequence is broken")
         raise SfaAPIError, "Argument to ManagerWrapper must be a module or class"
     self.interface = interface
Beispiel #41
0
 def __init__(self, config_file = "/etc/sfa/topology"):
     set.__init__(self) 
     try:
         # load the links
         f = open(config_file, 'r')
         for line in f:
             ignore = line.find('#')
             if ignore > -1:
                 line = line[0:ignore]
             tup = line.split()
             if len(tup) > 1:
                 self.add((tup[0], tup[1]))    
     except Exception, e:
         logger.log_exc("Could not find or load the configuration file: %s" % config_file)
         raise
Beispiel #42
0
    def get_version(self):
        ### if we already know the answer:
        if self.probed:
            return self._version
        ### otherwise let's look in the cache file
        logger.debug("searching in version cache %s" % self.url())
        cached_version = VersionCache().get(self.url())
        if cached_version is not None:
            logger.info("Retrieved version info from cache %s" % self.url())
            return cached_version
        ### otherwise let's do the hard work
        # dummy to meet Sfi's expectations for its 'options' field
        class DummyOptions:
            pass

        options = DummyOptions()
        options.verbose = self.verbose
        options.timeout = 10
        try:
            client = Sfi(options)
            client.read_config()
            client.bootstrap()
            key_file = client.private_key
            cert_file = client.my_gid
            logger.debug("using key %s & cert %s" % (key_file, cert_file))
            url = self.url()
            logger.info('issuing GetVersion at %s' % url)
            # setting timeout here seems to get the call to fail - even though the response time is fast
            #server=SfaServerProxy(url, key_file, cert_file, verbose=self.verbose, timeout=options.timeout)
            server = SfaServerProxy(url,
                                    key_file,
                                    cert_file,
                                    verbose=self.verbose)
            self._version = ReturnValue.get_value(server.GetVersion())
        except:
            logger.log_exc("failed to get version")
            self._version = {}
        # so that next run from this process will find out
        self.probed = True
        # store in version cache so next processes will remember for an hour
        cache = VersionCache()
        cache.set(self.url(), self._version)
        cache.save()
        logger.debug("Saved version for url=%s in version cache" % self.url())
        # that's our result
        return self._version
Beispiel #43
0
    def LaunchExperimentOnOAR(self, added_nodes, slice_name, \
                        lease_start_time, lease_duration, slice_user=None):
        """
        Create a job request structure based on the information provided
        and post the job on OAR.
        :param added_nodes: list of nodes that belong to the described lease.
        :param slice_name: the slice hrn associated to the lease.
        :param lease_start_time: timestamp of the lease startting time.
        :param lease_duration: lease durationin minutes

        """
        lease_dict = {}
        lease_dict['lease_start_time'] = lease_start_time
        lease_dict['lease_duration'] = lease_duration
        lease_dict['added_nodes'] = added_nodes
        lease_dict['slice_name'] = slice_name
        lease_dict['slice_user'] = slice_user
        lease_dict['grain'] = self.GetLeaseGranularity()
        lease_dict['time_format'] = self.time_format

        logger.debug("IOTLAB_API.PY \tLaunchExperimentOnOAR slice_user %s\
                             \r\n " % (slice_user))
        #Create the request for OAR
        reqdict = self._create_job_structure_request_for_OAR(lease_dict)
        # first step : start the OAR job and update the job
        logger.debug("IOTLAB_API.PY \tLaunchExperimentOnOAR reqdict %s\
                             \r\n " % (reqdict))

        answer = self.oar.POSTRequestToOARRestAPI('POST_job', \
                                                reqdict, slice_user)
        logger.debug("IOTLAB_API \tLaunchExperimentOnOAR jobid  %s " %
                     (answer))
        try:
            jobid = answer['id']
        except KeyError:
            logger.log_exc("IOTLAB_API \tLaunchExperimentOnOAR \
                                Impossible to create job  %s " % (answer))
            return None

        if jobid:
            logger.debug("IOTLAB_API \tLaunchExperimentOnOAR jobid %s \
                    added_nodes %s slice_user %s"                                                  %(jobid, added_nodes, \
                                                            slice_user))

        return jobid
Beispiel #44
0
    def POSTRequestToOARRestAPI(self, request, datadict, username=None):
        """ Used to post a job on OAR , along with data associated
        with the job.

        """

        #first check that all params for are OK
        try:
            self.oarserver['uri'] = \
                self.OAR_REQUEST_POST_URI_DICT[request]['uri']

        except KeyError:
            logger.log_exc("OARrestapi \tPOSTRequestToOARRestAPI request not \
                             valid")
            return
        if datadict and 'strval' in datadict:
            self.oarserver['uri'] = self.oarserver['uri'].replace("id", \
                                                str(datadict['strval']))
            del datadict['strval']

        data = json.dumps(datadict)
        headers = {'X-REMOTE_IDENT':username, \
                'content-type': self.POST_FORMAT['json']['content'], \
                'content-length':str(len(data))}
        try:

            conn = HTTPConnection(self.oarserver['ip'], \
                                        self.oarserver['port'])
            conn.request("POST", self.oarserver['uri'], data, headers)
            resp = conn.getresponse()
            body = resp.read()

        except NotConnected:
            logger.log_exc("POSTRequestToOARRestAPI NotConnected ERROR: \
                            data %s \r\n \t\n \t\t headers %s uri %s" \
                            %(data,headers,self.oarserver['uri']))
        except Exception as error:
            logger.log_exc("POST_OAR_SERVER : Connection error: %s " % (error))
            raise Exception("POST_OAR_SERVER : Connection error %s " % (error))

        finally:
            conn.close()

        if resp.status >= 400:
            raise ValueError("Response Error %s, %s" %
                             (resp.status, resp.reason))

        try:
            answer = json.loads(body)
            logger.debug("POSTRequestToOARRestAPI : answer %s" % (answer))
            return answer

        except ValueError, error:
            logger.log_exc("Failed to parse Server Response: error %s  \
                            %s" % (error))
Beispiel #45
0
    def exists(self, tablename):
        """
        Checks if the table specified as tablename exists.
        :param tablename: name of the table in the db that has to be checked.
        :type tablename: string
        :returns: True if the table exists, False otherwise.
        :rtype: bool

        """
        metadata = MetaData(bind=self.iotlab_engine)
        try:
            table = Table(tablename, metadata, autoload=True)
            return True

        except NoSuchTableError:
            logger.log_exc("IOTLABPOSTGRES tablename %s does not exist" %
                           (tablename))
            return False
Beispiel #46
0
 def _Allocate(aggregate, server, xrn, credential, rspec, options):
     tStart = time.time()
     try:
         # Need to call GetVersion at an aggregate to determine the supported
         # rspec type/format beofre calling CreateSliver at an Aggregate.
         #server_version = api.get_cached_server_version(server)
         #if 'sfa' not in server_version and 'geni_api' in server_version:
             # sfa aggregtes support both sfa and pg rspecs, no need to convert
             # if aggregate supports sfa rspecs. otherwise convert to pg rspec
             #rspec = RSpec(RSpecConverter.to_pg_rspec(rspec, 'request'))
             #filter = {'component_manager_id': server_version['urn']}
             #rspec.filter(filter)
             #rspec = rspec.toxml()
         result = server.Allocate(xrn, credential, rspec, options)
         return {"aggregate": aggregate, "result": result, "elapsed": time.time()-tStart, "status": "success"}
     except:
         logger.log_exc('Something wrong in _Allocate with URL %s'%server.url)
         return {"aggregate": aggregate, "elapsed": time.time()-tStart, "status": "exception", "exc_info": sys.exc_info()}
Beispiel #47
0
    def _process_ldap_info_for_all_users(self, result_data):
        """Process the data of all enabled users in LDAP.

        :param result_data: Contains information of all enabled users in LDAP
            and is coming from LdapSearch.
        :param result_data: list

        .. seealso:: LdapSearch

        """
        results = []
        logger.debug(" LDAP.py _process_ldap_info_for_all_users result_data %s "
                     % (result_data))
        for ldapentry in result_data:
            logger.debug(" LDAP.py _process_ldap_info_for_all_users \
                        ldapentry name : %s " % (ldapentry[1]['uid'][0]))
            tmpname = ldapentry[1]['uid'][0]
            hrn = self.authname + "." + tmpname

            tmpemail = ldapentry[1]['mail'][0]
            if ldapentry[1]['mail'][0] == "unknown":
                tmpemail = None

            try:
                results.append({
                    'type': 'user',
                    'pkey': ldapentry[1]['sshPublicKey'][0],
                    #'uid': ldapentry[1]['uid'][0],
                    'uid': tmpname ,
                    'email':tmpemail,
                    #'email': ldapentry[1]['mail'][0],
                    'first_name': ldapentry[1]['givenName'][0],
                    'last_name': ldapentry[1]['sn'][0],
                    #'phone': 'none',
                    'serial': 'none',
                    'authority': self.authname,
                    'peer_authority': '',
                    'pointer': -1,
                    'hrn': hrn,
                              })
            except KeyError, error:
                logger.log_exc("LDAPapi.PY \t LdapFindUser EXCEPTION %s"
                               % (error))
                return
Beispiel #48
0
    def add_rule_to_group(self,
                          group_name=None,
                          protocol='tcp',
                          cidr_ip='0.0.0.0/0',
                          port_range=None,
                          icmp_type_code=None,
                          source_group_name=None,
                          source_group_owner_id=None):

        try:
            from_port, to_port = self._validate_port_range(port_range)
            icmp_type = self._validate_icmp_type_code(icmp_type_code)
            if icmp_type and icmp_type[0] and icmp_type[1]:
                from_port, to_port = icmp_type[0], icmp_type[1]

            group = self.client.security_groups.find(name=group_name)
            self.client.security_group_rules.create(group.id, \
                                protocol, from_port, to_port,cidr_ip)
        except Exception, ex:
            logger.log_exc("Failed to add rule to group %s" % group_name)
Beispiel #49
0
    def filter_lease(reservation_list, filter_type, filter_value):
        """Filters the lease reservation list by removing each lease whose
        filter_type is not equal to the filter_value provided. Returns the list
        of leases in one slice, defined by the slice_hrn if filter_type
        is 'slice_hrn'. Otherwise, returns all leases scheduled starting from
        the filter_value if filter_type is 't_from'.

        :param reservation_list: leases list
        :type reservation_list: list of dictionary
        :param filter_type: can be either 't_from' or 'slice hrn'
        :type  filter_type: string
        :param filter_value: depending on the filter_type, can be the slice_hrn
            or can be defining a timespan.
        :type filter_value: if filter_type is 't_from', filter_value is int.
            if filter_type is 'slice_hrn', filter_value is a string.


        :returns: filtered_reservation_list, contains only leases running or
            scheduled in the given slice (wanted_slice).Dict keys are
            'lease_id','reserved_nodes','slice_id', 'state', 'user',
            'component_id_list','slice_hrn', 'resource_ids', 't_from', 't_until'
        :rtype: list of dict

        """
        filtered_reservation_list = list(reservation_list)
        logger.debug("IOTLAB_API \t filter_lease_name reservation_list %s" \
                        % (reservation_list))
        try:
            for reservation in reservation_list:
                if \
                (filter_type is 'slice_hrn' and \
                    reservation['slice_hrn'] != filter_value) or \
                (filter_type is 't_from' and \
                        reservation['t_from'] > filter_value):
                    filtered_reservation_list.remove(reservation)
        except TypeError:
            logger.log_exc("Iotlabshell filter_lease : filter_type %s \
                        filter_value %s not in lease" %
                           (filter_type, filter_value))

        return filtered_reservation_list
Beispiel #50
0
    def LdapDelete(self, person_dn):
        """Deletes a person in LDAP. Uses the dn of the user.

        :param person_dn: user's ldap dn.
        :type person_dn: string
        :returns: dictionary with bool True if successful, bool False
            and the error if not.
        :rtype: dict

        """
        #Connect and bind
        result =  self.conn.connect()
        if(result['bool']):
            try:
                self.conn.ldapserv.delete_s(person_dn)
                self.conn.close()
                return {'bool': True}

            except ldap.LDAPError, error:
                logger.log_exc("LDAP Delete Error %s" % error)
                return {'bool': False, 'message': error}
Beispiel #51
0
    def ParseJobsIds(self):
        """Associated with the GET_jobs_id OAR request.

        Parses the json dict (OAR answer) to the GET_jobs_id request
        /oarapi/jobs/id.json.


        :returns: dictionary whose keys are listed in the local variable
            job_resources and values that are in the json dictionary returned
            by OAR with the job information.
        :rtype: dict

        """
        job_resources = [
            'wanted_resources', 'name', 'id', 'start_time', 'state', 'owner',
            'walltime', 'message'
        ]

        # Unused variable providing the contents of the json dict returned from
        # get job resources full request
        job_resources_full = [
            'launching_directory', 'links', 'resubmit_job_id', 'owner',
            'events', 'message', 'scheduled_start', 'id', 'array_id',
            'exit_code', 'properties', 'state', 'array_index', 'walltime',
            'type', 'initial_request', 'stop_time', 'project', 'start_time',
            'dependencies', 'api_timestamp', 'submission_time', 'reservation',
            'stdout_file', 'types', 'cpuset_name', 'name', 'wanted_resources',
            'queue', 'stderr_file', 'command'
        ]

        job_info = self.json_page.raw_json
        #logger.debug("OARESTAPI ParseJobsIds %s" %(self.json_page.raw_json))
        values = []
        try:
            for k in job_resources:
                values.append(job_info[k])
            return dict(zip(job_resources, values))

        except KeyError:
            logger.log_exc("ParseJobsIds KeyError ")
Beispiel #52
0
    def __call__(self, *args, **kwds):
        """
        Main entry point for all SFA API functions. Type checks
        arguments, authenticates, and executes call().
        """

        try:
            start = time.time()
            methodname = self.name
            if not self.api.interface or self.api.interface not in self.interfaces:
                raise SfaInvalidAPIMethod(methodname, self.api.interface) 

            (min_args, max_args, defaults) = self.args()
	    		
            # Check that the right number of arguments were passed in
            if len(args) < len(min_args) or len(args) > len(max_args):
                raise SfaInvalidArgumentCount(len(args), len(min_args), len(max_args))

            for name, value, expected in zip(max_args, args, self.accepts):
                self.type_check(name, value, expected, args)

            logger.debug("method.__call__ [%s] : BEG %s"%(self.api.interface,methodname))
            result = self.call(*args, **kwds)

            runtime = time.time() - start
            logger.debug("method.__call__ [%s] : END %s in %02f s (%s)"%\
                             (self.api.interface,methodname,runtime,getattr(self,'message',"[no-msg]")))

            return result

        except SfaFault, fault:

            caller = ""

            # Prepend caller and method name to expected faults
            fault.faultString = caller + ": " +  self.name + ": " + fault.faultString
            runtime = time.time() - start
            logger.log_exc("Method %s raised an exception"%self.name) 
            raise fault
Beispiel #53
0
def handler(req):
    try:
        if req.method != "POST":
            req.content_type = "text/html"
            req.send_http_header()
            req.write("""
<html><head>
<title>SFA SliceMgr API XML-RPC/SOAP Interface</title>
</head><body>
<h1>SFA SliceMgr API XML-RPC/SOAP Interface</h1>
<p>Please use XML-RPC or SOAP to access the SFA API.</p>
</body></html>
""")
            return apache.OK

        # Read request
        request = req.read(int(req.headers_in['content-length']))

        # mod_python < 3.2: The IP address portion of remote_addr is
        # incorrect (always 0.0.0.0) when IPv6 is enabled.
        # http://issues.apache.org/jira/browse/MODPYTHON-64?page=all
        (remote_ip, remote_port) = req.connection.remote_addr
        remote_addr = (req.connection.remote_ip, remote_port)

        # Handle request
        response = api.handle(remote_addr, request)

        # Write response
        req.content_type = "text/xml; charset=" + api.encoding
        req.send_http_header()
        req.write(response)

        return apache.OK

    except Exception, err:
        # Log error in /var/log/httpd/(ssl_)?error_log
        logger.log_exc('%r'%err)
        return apache.HTTP_INTERNAL_SERVER_ERROR