예제 #1
0
 def list_resources(self, version=None, options=None):
     logger.warning("iotlabdriver list_resources")
     if not options:
         options = {}
     aggregate = IotLABAggregate(self)
     rspec = aggregate.list_resources(version=version, options=options)
     return rspec
예제 #2
0
    def get_users(self):
        """
        Get all LDAP users
        :returns: users with LDAP attributes
        :rtype: dict

        :Example:
        [{"firstName":"Frederic",
          "lastName":"Saint-marcel",
          "email":"*****@*****.**",
          "structure":"INRIA",
          "city":"Grenoble",
          "country":"France",
          "login":"******",
          sshPublicKeys":["ssh-rsa AAAAB3..."],
          "motivations":"test SFA",
          "validate":true,
          "admin":true,
          "createTimeStamp":"20120911115247Z"},
          {"firstName":"Julien",
           ...
          }
        ]
        """
        logger.warning("iotlashell get_users")
        users_dict = {}
        try:
            users = self.api.method('admin/users')
        except HTTPError as err:
            logger.warning("iotlashell get_users error %s" % err.reason)
            return {'error' : err.reason}
        for user in users:
            users_dict[user['email']] = user
        return users_dict
예제 #3
0
파일: sfascan.py 프로젝트: aquila/sfa
    def __init__ (self,url,mentioned_in=None,verbose=False):
        self._url=url
        self.verbose=verbose
        cache=VersionCache()
        key="interface:%s"%url
        try:
            (self._url,self.hostname,self.port)=url_hostname_port(url)
            # look for ip in the cache
            tuple=cache.get(key)
            if tuple:
                (self.hostname, self.ip, self.port) = tuple
            else:
                self.ip=socket.gethostbyname(self.hostname)
        except:
            msg="can't resolve hostname %s\n\tfound in url %s"%(self.hostname,self._url)
            if mentioned_in:
                msg += "\n\t(mentioned at %s)"%mentioned_in
            logger.warning (msg)
            self.hostname="unknown"
            self.ip='0.0.0.0'
            self.port="???"

        cache.set(key, (self.hostname, self.ip, self.port,) )
        cache.save()
        self.probed=False

        # mark unknown interfaces as probed to avoid unnecessary attempts
        if self.hostname=='unknown':
            # don't really try it
            self.probed=True
            self._version={}
예제 #4
0
 def status(self, urns, options=None):
     logger.warning("iotlabdriver status")
     aggregate = IotLABAggregate(self)
     desc = aggregate.describe(urns, version='GENI 3')
     status = {'geni_urn': desc['geni_urn'],
               'geni_slivers': desc['geni_slivers']}
     return status
예제 #5
0
파일: callids.py 프로젝트: gnogueras/sfa
 def already_handled(self, call_id):
     # if not provided in the call...
     if not call_id: return False
     has_lock = False
     for attempt in range(_call_ids_impl.retries):
         if debug: logger.debug("Waiting for lock (%d)" % attempt)
         if self._lock.acquire(False):
             has_lock = True
             if debug: logger.debug("got lock (%d)" % attempt)
             break
         time.sleep(float(_call_ids_impl.wait_ms) / 1000)
     # in the unlikely event where we can't get the lock
     if not has_lock:
         logger.warning(
             "_call_ids_impl.should_handle_call_id: could not acquire lock")
         return False
     # we're good to go
     if self.has_key(call_id):
         self._purge()
         self._lock.release()
         return True
     self[call_id] = time.time()
     self._purge()
     self._lock.release()
     if debug: logger.debug("released lock")
     return False
예제 #6
0
 def call(self):
     if hasattr(self.api.manager, 'get_key_from_incoming_ip'):
         return self.api.manager.get_key_from_incoming_ip(api)
     else:
         logger.warning(
             "get_key_from_incoming_ip not supported by registry manager")
         return 0
예제 #7
0
    def get_nodes(self):
        """
        Get all OAR nodes
        :returns: nodes with OAR properties
        :rtype: dict

        :Example:
        {"items": [
            {"archi": "a8:at86rf231",
             "mobile": 0,
             "mobility_type": " ",
             "network_address": "a8-53.grenoble.iot-lab.info",
             "site": "paris",
             "state": "Alive",
             "uid": "9856",
             "x": "0.37",
             "y": "5.44",
             "z": "2.33"
            },
            {"archi= ...}
          ]
        {
        """
        logger.warning("iotlashell get_nodes")
        nodes_dict = {}
        try:
            nodes = experiment.info_experiment(self.api)
        except HTTPError as err:
            logger.warning("iotlashell get_nodes error %s" % err.reason)
            return {'error' : err.reason}
        for node in nodes['items']:
            nodes_dict[node['network_address']] = node
        return nodes_dict
예제 #8
0
 def add_user(self, slice_user):
     """
     Add LDAP user
     """
     # pylint:disable=E1123
     logger.warning("iotlashell add_user")
     user = {"type" : "SA", # single account creation
             "city" : "To be defined",
             "country" : "To be defined",
             "motivations" : "SFA federation"}
     email = slice_user['email']
     user['email'] = email
     user['sshPublicKey'] = slice_user['keys'][0]
     # ex : onelab.inria
     user['structure'] = slice_user['slice_record']['authority']
     email = (email.split('@'))[0]
     user['firstName'] = email.split('.')[0]
     try:
         user['lastName'] = email.split('.')[1]
     except IndexError:
         user['lastName'] = email.split('.')[0]
     try:
         self.api.method('admin/users', 'post',
                     json=user)
     except HTTPError as err:
         logger.warning("iotlashell add_user error %s" % err.reason)
예제 #9
0
파일: callids.py 프로젝트: aquila/sfa
 def already_handled (self,call_id):
     # if not provided in the call...
     if not call_id: return False
     has_lock=False
     for attempt in range(_call_ids_impl.retries):
         if debug: logger.debug("Waiting for lock (%d)"%attempt)
         if self._lock.acquire(False): 
             has_lock=True
             if debug: logger.debug("got lock (%d)"%attempt)
             break
         time.sleep(float(_call_ids_impl.wait_ms)/1000)
     # in the unlikely event where we can't get the lock
     if not has_lock:
         logger.warning("_call_ids_impl.should_handle_call_id: could not acquire lock")
         return False
     # we're good to go
     if self.has_key(call_id):
         self._purge()
         self._lock.release()
         return True
     self[call_id]=time.time()
     self._purge()
     self._lock.release()
     if debug: logger.debug("released lock")
     return False
예제 #10
0
 def _save_db_lease(self, job_id, slice_hrn):
     """ Save lease table row in SFA database """
     lease_row = LeaseTable(job_id,
                            slice_hrn)
     logger.warning("iotlabdriver _save_db_lease lease row : %s" %
                    lease_row)
     self.api.dbsession().add(lease_row)
     self.api.dbsession().commit()
예제 #11
0
 def response(self, from_xmlrpc):
     if isinstance(from_xmlrpc, dict) and 'code' in from_xmlrpc:
         if from_xmlrpc['code'] == 0:
             return from_xmlrpc['value']
         else:
             raise SfaFault(from_xmlrpc['code'], from_xmlrpc['output'])
     else:
         logger.warning("unexpected result from federica xmlrpc api")
         return from_xmlrpc
예제 #12
0
파일: fddriver.py 프로젝트: tubav/sfa
 def response (self, from_xmlrpc):
     if isinstance (from_xmlrpc, dict) and 'code' in from_xmlrpc:
         if from_xmlrpc['code']==0:
             return from_xmlrpc['value']
         else:
             raise SfaFault(from_xmlrpc['code'],from_xmlrpc['output'])
     else:
         logger.warning("unexpected result from federica xmlrpc api")
         return from_xmlrpc
예제 #13
0
 def get_file_list(self):
     file_list  = []
     pattern=os.path.join(self.basedir,"*")
     for cert_file in glob.glob(pattern):
         if os.path.isfile(cert_file):
             if self.has_supported_extension(cert_file):
                 file_list.append(cert_file) 
             else:
                 logger.warning("File %s ignored - supported extensions are %r"%\
                                    (cert_file,TrustedRoots.supported_extensions))
     return file_list
예제 #14
0
def _normalize_input (record, reg_key, driver_key):
    # this looks right, use this for both keys
    if reg_key in record:
        # and issue a warning if they were both set and different
        # as we're overwriting some user data here
        if driver_key in record:
            logger.warning ("normalize_input: incoming record has both values, using %s"%reg_key)
        record[driver_key]=record[reg_key]
    # we only have one key set, duplicate for the other one
    elif driver_key in record:
        logger.warning ("normalize_input: you should use '%s' instead of '%s'"%(reg_key,driver_key))
        record[reg_key]=record[driver_key]
예제 #15
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']}
예제 #16
0
 def aggregate_version(self):
     logger.warning("iotlabdriver aggregate_version")
     version_manager = VersionManager()
     ad_rspec_versions = []
     request_rspec_versions = []
     for rspec_version in version_manager.versions:
         if rspec_version.content_type in ['*', 'ad']:
             ad_rspec_versions.append(rspec_version.to_dict())
         if rspec_version.content_type in ['*', 'request']:
             request_rspec_versions.append(rspec_version.to_dict())
     return {
         'testbed': self.hrn,
         'geni_request_rspec_versions': request_rspec_versions,
         'geni_ad_rspec_versions': ad_rspec_versions}
예제 #17
0
 def get_slivers(self, urns, leases, nodes):
     """ Get slivers attributes list """
     logger.warning("iotlabaggregate get_slivers")
     logger.warning("iotlabaggregate get_slivers urns %s" % urns)
     slivers = []
     for lease in leases:
         for node in lease["resources"]:
             sliver_node = nodes[node]
             sliver_hrn = "%s.%s-%s" % (self.driver.hrn, lease["id"], node.split(".")[0])
             start_time = datetime.datetime.fromtimestamp(lease["date"])
             duration = datetime.timedelta(seconds=int(lease["duration"]))
             sliver_node["expires"] = start_time + duration
             sliver_node["sliver_id"] = Xrn(sliver_hrn, type="sliver").urn
             slivers.append(sliver_node)
     return slivers
예제 #18
0
    def create_user(self, user_name, password, tenant_id, email=None, enabled=True):
        if password is None:
            logger.warning("If you want to make a user, you should include your password!!")
            raise ValueError('You should include your password!!')

        users = self.driver.shell.auth_manager.users.findall()
        for user in users:
            if user_name == user.name:
                user_info = user
                logger.info("The user name[%s] already exists." % user_name)
                break
        else:
            user_info = self.driver.shell.auth_manager.users.create(user_name, password, \
                                                             email, tenant_id, enabled)
        return user_info
예제 #19
0
    def DeletePerson(self, person_record):
        """Disable an existing account in cortexlab LDAP.

        Users and techs can only delete themselves. PIs can only
            delete themselves and other non-PIs at their sites.
            ins can delete anyone.

        :param person_record: user's record
        :type person_record: dict
        :returns:  True if successful, False otherwise.
        :rtype: boolean

        .. todo:: CHECK THAT ONLY THE USER OR ADMIN CAN DEL HIMSELF.
        """
        #Disable user account in iotlab LDAP
        ret = self.ldap.LdapMarkUserAsDeleted(person_record)
        logger.warning("CORTEXLAB_API DeletePerson %s " % (person_record))
        return ret['bool']
예제 #20
0
    def DeletePerson(self, person_record):
        """Disable an existing account in iotlab LDAP.

        Users and techs can only delete themselves. PIs can only
            delete themselves and other non-PIs at their sites.
            ins can delete anyone.

        :param person_record: user's record
        :type person_record: dict
        :returns:  True if successful, False otherwise.
        :rtype: boolean

        .. todo:: CHECK THAT ONLY THE USER OR ADMIN CAN DEL HIMSELF.
        """
        #Disable user account in iotlab LDAP
        ret = self.ldap.LdapMarkUserAsDeleted(person_record)
        logger.warning("IOTLAB_API DeletePerson %s " % (person_record))
        return ret['bool']
예제 #21
0
파일: hierarchy.py 프로젝트: planetlab/sfa
    def get_auth_info(self, xrn):
        hrn, type = urn_to_hrn(xrn)
        if not self.auth_exists(hrn):
            logger.warning("Hierarchy: mising authority - xrn=%s, hrn=%s"%(xrn,hrn))
            raise MissingAuthority(hrn)

        (directory, gid_filename, privkey_filename, dbinfo_filename) = \
            self.get_auth_filenames(hrn)

        auth_info = AuthInfo(hrn, gid_filename, privkey_filename, dbinfo_filename)

        # check the GID and see if it needs to be refreshed
        gid = auth_info.get_gid_object()
        gid_refreshed = self.refresh_gid(gid)
        if gid != gid_refreshed:
            auth_info.update_gid_object(gid_refreshed)

        return auth_info
예제 #22
0
    def get_auth_info(self, xrn):
        hrn, type = urn_to_hrn(xrn)
        if not self.auth_exists(hrn):
            logger.warning("Hierarchy: missing authority - xrn=%s, hrn=%s"%(xrn,hrn))
            raise MissingAuthority(hrn)

        (directory, gid_filename, privkey_filename, ) = \
            self.get_auth_filenames(hrn)

        auth_info = AuthInfo(hrn, gid_filename, privkey_filename)

        # check the GID and see if it needs to be refreshed
        gid = auth_info.get_gid_object()
        gid_refreshed = self.refresh_gid(gid)
        if gid != gid_refreshed:
            auth_info.update_gid_object(gid_refreshed)

        return auth_info
예제 #23
0
파일: LDAPapi.py 프로젝트: tubav/sfa
    def LdapAddUser(self, record) :
        """Add SFA user to LDAP if it is not in LDAP  yet. """
        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']}  
예제 #24
0
 def reserve_nodes(self, login, exp_name,
                   nodes_list, start_time, duration):
     """
     Submit a physical experiment (nodes list) and reservation date.
     """
     # pylint:disable=W0212,R0913,E1123
     logger.warning("iotlashell reserve_nodes")
     exp_file = helpers.FilesDict()
     _experiment = experiment._Experiment(exp_name, duration, start_time)
     _experiment.type = 'physical'
     _experiment.nodes = nodes_list
     exp_file['new_exp.json'] = helpers.json_dumps(_experiment)
     try:
         return self.api.method('admin/experiments?user=%s' % login,
                                'post',
                                files=exp_file)
     except HTTPError as err:
         logger.warning("iotlashell reserve_nodes error %s" % err.reason)
         return {'error' : err.reason}
예제 #25
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
예제 #26
0
    def AddPersonKey(self, person_uid, old_attributes_dict, new_key_dict):
        """Adds a new key to the specified account. Adds the key to the
            iotlab ldap, provided that the person_uid is valid.

        Non-admins can only modify their own keys.

        :param person_uid: user's iotlab login in LDAP
        :param old_attributes_dict: dict with the user's old sshPublicKey
        :param new_key_dict: dict with the user's new sshPublicKey
        :type person_uid: string


        :rtype: Boolean
        :returns: True if the key has been modified, False otherwise.

        """
        ret = self.ldap.LdapModify(person_uid, old_attributes_dict, \
                                                                new_key_dict)
        logger.warning("IOTLAB_API AddPersonKey EMPTY - DO NOTHING \r\n ")
        return ret['bool']
예제 #27
0
    def AddPersonKey(self, person_uid, old_attributes_dict, new_key_dict):
        """Adds a new key to the specified account. Adds the key to the
            iotlab ldap, provided that the person_uid is valid.

        Non-admins can only modify their own keys.

        :param person_uid: user's iotlab login in LDAP
        :param old_attributes_dict: dict with the user's old sshPublicKey
        :param new_key_dict: dict with the user's new sshPublicKey
        :type person_uid: string


        :rtype: Boolean
        :returns: True if the key has been modified, False otherwise.

        """
        ret = self.ldap.LdapModify(person_uid, old_attributes_dict, \
                                                                new_key_dict)
        logger.warning("CORTEXLAB_API AddPersonKey EMPTY - DO NOTHING \r\n ")
        return ret['bool']
예제 #28
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
예제 #29
0
파일: sfascan.py 프로젝트: gnogueras/sfa
    def __init__(self, url, mentioned_in=None, verbose=False):
        self._url = url
        self.verbose = verbose
        cache = VersionCache()
        key = "interface:%s" % url
        try:
            (self._url, self.hostname, self.port) = url_hostname_port(url)
            # look for ip in the cache
            tuple = cache.get(key)
            if tuple:
                (self.hostname, self.ip, self.port) = tuple
            else:
                self.ip = socket.gethostbyname(self.hostname)
        except:
            msg = "can't resolve hostname %s\n\tfound in url %s" % (
                self.hostname, self._url)
            if mentioned_in:
                msg += "\n\t(mentioned at %s)" % mentioned_in
            logger.warning(msg)
            self.hostname = "unknown"
            self.ip = '0.0.0.0'
            self.port = "???"

        cache.set(key, (
            self.hostname,
            self.ip,
            self.port,
        ))
        cache.save()
        self.probed = False

        # mark unknown interfaces as probed to avoid unnecessary attempts
        if self.hostname == 'unknown':
            # don't really try it
            self.probed = True
            self._version = {}
예제 #30
0
 def create_floatingip(self, tenant_name, instances):
     config = OSConfig()
     # Information of public network(external network) from configuration file
     extnet_name = config.get('network', 'external_network_name')
     tenant = self.driver.shell.auth_manager.tenants.find(name=tenant_name)
     networks = self.driver.shell.network_manager.list_networks().get('networks')
     for network in networks:
         if (network.get('name') == extnet_name) or \
            (network.get('name') == 'public') or (network.get('name') == 'ext-net'):
             pub_net_id = network.get('id')
             break
     else:
         logger.warning("We shoud need the public network ID for floating IPs!")
         raise ValueError("The public network ID was not found!")
     ports = self.driver.shell.network_manager.list_ports().get('ports')
     for port in ports:
         device_id = port.get('device_id')
         for instance in instances:
             if device_id == instance.id:
                 body = { "floatingip":
                          { "floating_network_id": pub_net_id,
                            "tenant_id": tenant.id,
                            "port_id": port.get('id') } }
                 self.driver.shell.network_manager.create_floatingip(body=body)
예제 #31
0
    def get_reserved_nodes(self):
        """
        Get all OAR jobs with state Waiting or Running.

        :Example:
        {"total":"1907",
         "items":[
             {"id":9960,
              "resources": ["m3-16.devgrenoble.iot-lab.info",...],
              "duration":"36000",
              "name":"test_sniffer",
              "state":"Running",
              "owner":"saintmar",
              "nb_resources":10,
              "date":1427966468},
              {"id": ...}
         ]
        }
        """
        logger.warning("iotlashell get_reserved_nodes")
        reserved_nodes_dict = {}
        request = 'admin/experiments?state=Running,Waiting'
        try:
            experiments = self.api.method(request)
        except HTTPError as err:
            logger.warning("iotlashell get_reserved_nodes error %s" %
                           err.reason)
            return {'error' : err.reason}
        for exp in experiments['items']:
            # BUG IN OAR REST API : job with reservation didn't return
            # resources attribute list
            # we use another request for finding job resources
            exp_nodes = self.api.method('admin/experiments/%d' % exp['id'])
            exp['resources'] = exp_nodes['nodes']
            reserved_nodes_dict[exp['id']] = exp
        return reserved_nodes_dict
예제 #32
0
    def allocate(self, urn, rspec_string, expiration, options=None):
        """
        Allocate method submit an experiment on Iot-LAB testbed with :
            * user : get the slice user which launch request (caller_hrn)
            * reservation : get the start time and duration in RSpec leases
            * nodes : get the nodes list in RSpec leases
        If we have a request success on Iot-LAB testbed we store in SFA
        database the assocation OAR scheduler job id and slice hrn

        :param urn : slice urn
        :param rspec_string : RSpec received
        :param options : options with slice users (geni_users)
        """
        # pylint:disable=R0914

        logger.warning("iotlabdriver allocate")
        xrn = Xrn(urn)
        aggregate = IotLABAggregate(self)
        # parse rspec
        rspec = RSpec(rspec_string)

        caller_hrn = options.get('actual_caller_hrn', [])
        geni_users = options.get('geni_users', [])
        caller_user = [user for user in geni_users if
                       urn_to_hrn(user['urn'])[0] == caller_hrn][0]
        logger.warning("iotlabdriver allocate caller : %s" %
                       caller_user['email'])

        login = self._get_user_login(caller_user)
        # only if we have a user
        if login:
            nodes_list, start_time, duration = \
                self._get_experiment(rspec)
            logger.warning("iotlabdriver allocate submit OAR job :"
                           " %s %s %s %s" %
                           (xrn.hrn, start_time, duration, nodes_list))
            # [0-9A-Za-z_] with onelab.inria.test_iotlab
            exp_name = '_'.join((xrn.hrn).split('.'))
            # submit OAR job
            ret = self.shell.reserve_nodes(login,
                                           exp_name,
                                           nodes_list,
                                           start_time,
                                           duration)

            # in case of job submission success save slice and lease job
            # id association in database
            if 'id' in ret:
                self._save_db_lease(int(ret['id']),
                                    xrn.hrn)

        return aggregate.describe([xrn.get_urn()], version=rspec.version)
예제 #33
0
 def _delete_db_lease(self, job_id):
     """ Delete lease table row in SFA database """
     logger.warning("iotlabdriver _delete_db_lease lease job_id : %s" % job_id)
     self.driver.api.dbsession().query(LeaseTable).filter(LeaseTable.job_id == job_id).delete()
     self.driver.api.dbsession().commit()
예제 #34
0
    def get_slivers(self, urns, options={}):
        """Get slivers of the given slice urns. Slivers contains slice, node and
        user information.

        For Iotlab, returns the leases with sliver ids and their allocation
        status.

        :param urns: list of  slice urns.
        :type urns: list of strings
        :param options: unused
        :type options: unused

        .. seealso:: http://groups.geni.net/geni/wiki/GAPI_AM_API_V3/CommonConcepts#urns
        """

        slice_ids = set()
        node_ids = []
        for urn in urns:
            xrn = IotlabXrn(xrn=urn)
            if xrn.type == 'sliver':
                # id: slice_id-node_id
                try:
                    sliver_id_parts = xrn.get_sliver_id_parts()
                    slice_id = int(sliver_id_parts[0])
                    node_id = int(sliver_id_parts[1])
                    slice_ids.add(slice_id)
                    node_ids.append(node_id)
                except ValueError:
                    pass
            else:
                slice_names = set()
                slice_names.add(xrn.hrn)

        logger.debug("CortexlabAggregate \t get_slivers urns %s slice_ids %s \
                       node_ids %s\r\n" % (urns, slice_ids, node_ids))
        logger.debug("CortexlabAggregate \t get_slivers xrn %s slice_names %s \
                       \r\n" % (xrn, slice_names))
        filter_sliver = {}
        if slice_names:
            filter_sliver['slice_hrn'] = list(slice_names)
            slice_hrn = filter_sliver['slice_hrn'][0]

            slice_filter_type = 'slice_hrn'

        # if slice_ids:
        #     filter['slice_id'] = list(slice_ids)
        # # get slices
        if slice_hrn:
            slices = self.driver.GetSlices(slice_hrn, slice_filter_type)
            leases = self.driver.GetLeases({'slice_hrn': slice_hrn})
        logger.debug("CortexlabAggregate \t get_slivers \
                       slices %s leases %s\r\n" % (slices, leases))
        if not slices:
            return []

        single_slice = slices[0]
        # get sliver users
        user = single_slice['reg_researchers'][0].__dict__
        logger.debug("CortexlabAggregate \t get_slivers user %s \
                       \r\n" % (user))

        # construct user key info
        person = self.driver.testbed_shell.ldap.LdapFindUser(record=user)
        logger.debug("CortexlabAggregate \t get_slivers person %s \
                       \r\n" % (person))
        # name = person['last_name']
        user['login'] = person['uid']
        user['user_urn'] = hrn_to_urn(user['hrn'], 'user')
        user['keys'] = person['pkey']

        try:
            node_ids = single_slice['node_ids']
            node_list = self.driver.testbed_shell.GetNodes(
                {'hostname': single_slice['node_ids']})
            node_by_hostname = dict([(node['hostname'], node)
                                     for node in node_list])
        except KeyError:
            logger.warning("\t get_slivers No slivers in slice")
            # slice['node_ids'] = node_ids
        # nodes_dict = self.get_slice_nodes(slice, options)

        slivers = []
        for current_lease in leases:
            for hostname in current_lease['reserved_nodes']:
                node = {}
                node['slice_id'] = current_lease['slice_id']
                node['slice_hrn'] = current_lease['slice_hrn']
                slice_name = current_lease['slice_hrn'].split(".")[1]
                node['slice_name'] = slice_name
                index = current_lease['reserved_nodes'].index(hostname)
                node_id = current_lease['resource_ids'][index]
                # node['slice_name'] = user['login']
                # node.update(single_slice)
                more_info = node_by_hostname[hostname]
                node.update(more_info)
                # oar_job_id is the slice_id (lease_id)
                sliver_hrn = '%s.%s-%s' % (self.driver.hrn,
                                           current_lease['lease_id'], node_id)
                node['node_id'] = node_id
                node['expires'] = current_lease['t_until']
                node['sliver_id'] = Xrn(sliver_hrn, type='sliver').urn
                node['urn'] = node['sliver_id']
                node['services_user'] = [user]

                slivers.append(node)
        return slivers
예제 #35
0
    def get_slivers(self, urns, options=None):
        """Get slivers of the given slice urns. Slivers contains slice, node and
        user information.

        For Iotlab, returns the leases with sliver ids and their allocation
        status.

        :param urns: list of  slice urns.
        :type urns: list of strings
        :param options: unused
        :type options: unused

        .. seealso:: http://groups.geni.net/geni/wiki/GAPI_AM_API_V3/CommonConcepts#urns
        """

        if options is None: options={}
        slice_ids = set()
        node_ids = []
        for urn in urns:
            xrn = IotlabXrn(xrn=urn)
            if xrn.type == 'sliver':
                 # id: slice_id-node_id
                try:
                    sliver_id_parts = xrn.get_sliver_id_parts()
                    slice_id = int(sliver_id_parts[0])
                    node_id = int(sliver_id_parts[1])
                    slice_ids.add(slice_id)
                    node_ids.append(node_id)
                except ValueError:
                    pass
            else:
                slice_names = set()
                slice_names.add(xrn.hrn)


        logger.debug("IotlabAggregate \t get_slivers urns %s slice_ids %s \
                       node_ids %s\r\n" % (urns, slice_ids, node_ids))
        logger.debug("IotlabAggregate \t get_slivers xrn %s slice_names %s \
                       \r\n" % (xrn, slice_names))
        filter_sliver = {}
        if slice_names:
            filter_sliver['slice_hrn'] = list(slice_names)
            slice_hrn = filter_sliver['slice_hrn'][0]

            slice_filter_type = 'slice_hrn'

        # if slice_ids:
        #     filter['slice_id'] = list(slice_ids)
        # # get slices
        if slice_hrn:
            slices = self.driver.GetSlices(slice_hrn,
                slice_filter_type)
            leases = self.driver.GetLeases({'slice_hrn':slice_hrn})
        logger.debug("IotlabAggregate \t get_slivers \
                       slices %s leases %s\r\n" % (slices, leases ))
        if not slices:
            return []

        single_slice = slices[0]
        # get sliver users
        user = single_slice['reg_researchers'][0].__dict__
        logger.debug("IotlabAggregate \t get_slivers user %s \
                       \r\n" % (user))

        # construct user key info
        person = self.driver.testbed_shell.ldap.LdapFindUser(record=user)
        logger.debug("IotlabAggregate \t get_slivers person %s \
                       \r\n" % (person))
        # name = person['last_name']
        user['login'] = person['uid']
        user['user_urn'] = hrn_to_urn(user['hrn'], 'user')
        user['keys'] = person['pkey']


        try:
            node_ids = single_slice['node_ids']
            node_list = self.driver.testbed_shell.GetNodes(
                    {'hostname':single_slice['node_ids']})
            node_by_hostname = dict([(node['hostname'], node)
                                        for node in node_list])
        except KeyError:
            logger.warning("\t get_slivers No slivers in slice")
            # slice['node_ids'] = node_ids
        # nodes_dict = self.get_slice_nodes(slice, options)

        slivers = []
        for current_lease in leases:
            for hostname in current_lease['reserved_nodes']:
                node = {}
                node['slice_id'] = current_lease['slice_id']
                node['slice_hrn'] = current_lease['slice_hrn']
                slice_name = current_lease['slice_hrn'].split(".")[1]
                node['slice_name'] = slice_name
                index = current_lease['reserved_nodes'].index(hostname)
                node_id = current_lease['resource_ids'][index]
                # node['slice_name'] = user['login']
                # node.update(single_slice)
                more_info = node_by_hostname[hostname]
                node.update(more_info)
                # oar_job_id is the slice_id (lease_id)
                sliver_hrn = '%s.%s-%s' % (self.driver.hrn,
                            current_lease['lease_id'], node_id)
                node['node_id'] = node_id
                node['expires'] = current_lease['t_until']
                node['sliver_id'] = Xrn(sliver_hrn, type='sliver').urn
                node['urn'] = node['sliver_id']
                node['services_user'] = [user]

                slivers.append(node)
        return slivers
예제 #36
0
 def describe(self, urns, version, options=None):
     logger.warning("iotlabdriver describe")
     if not options:
         options = {}
     aggregate = IotLABAggregate(self)
     return aggregate.describe(urns, version=version, options=options)
예제 #37
0
 def run_sfatables(_, __, ___, rspec, ____=None):
     logger.warning(
         "Cannot import sfatables.runtime, please install package sfa-sfatables"
     )
     return rspec
예제 #38
0
            # up to fedora20 we used os.popen and checked that the output begins with OK
            # turns out, with fedora21, there is extra input before this 'OK' thing
            # looks like we're better off just using the exit code - that's what it is made for
            #cert_args = " ".join(['--trusted-pem %s' % x for x in trusted_certs])
            #command = '{} --verify --node-id "{}" {} {} 2>&1'.\
            #          format(self.xmlsec_path, ref, cert_args, filename)
            command = [ self.xmlsec_path, '--verify', '--node-id', ref ]
            for trusted in trusted_certs:
                command += ["--trusted-pem", trusted ]
            command += [ filename ]
            logger.debug("Running " + " ".join(command))
            try:
                verified = subprocess.check_output(command, stderr=subprocess.STDOUT)
                logger.debug("xmlsec command returned {}".format(verified))
                if "OK\n" not in verified:
                    logger.warning("WARNING: xmlsec1 seemed to return fine but without a OK in its output")
            except subprocess.CalledProcessError as e:
                verified = e.output
                # xmlsec errors have a msg= which is the interesting bit.
                mstart = verified.find("msg=")
                msg = ""
                if mstart > -1 and len(verified) > 4:
                    mstart = mstart + 4
                    mend = verified.find('\\', mstart)
                    msg = verified[mstart:mend]
                logger.warning("Credential.verify - failed - xmlsec1 returned {}".format(verified.strip()))
                raise CredentialNotVerifiable("xmlsec1 error verifying cred %s using Signature ID %s: %s" % \
                                              (self.pretty_cred(), ref, msg))
        os.remove(filename)

        # Verify the parents (delegation)
예제 #39
0
    def describe(self, urns, version=None, options=None):
        """
        describe method returns slice slivers (allocated resources) and leases
        (OAR job submission). We search in lease table of SFA database all OAR
        jobs id for this slice and match OAR jobs with state Waiting or Running.
        If OAR job id doesn't exist the experiment is terminated and we delete
        the database table entry. Otherwise we add slivers and leases in the
        response

        :returns:
            geni_slivers : a list of allocated slivers with information about
                           their allocation and operational state
            geni_urn : the URN of the slice in which the sliver has been
                       allocated
            geni_rspec:  a RSpec describing the allocated slivers and leases
        :rtype: dict

        :Example:
        <rspec>
        ...
        <node component_manager_id="urn:publicid:IDN+iotlab+authority+sa"
              component_id=
                  "urn:publicid:IDN+iotlab+node+m3-10.grenoble.iot-lab.info"
              client_id="m3-10.grenoble.iot-lab.info"
              sliver_id="urn:publicid:IDN+iotlab+sliver+9953-m3-10"
              exclusive="true" component_name="m3-10.grenoble.iot-lab.info">
            <hardware_type name="iotlab-node"/>
            <location country="France"/>
            <granularity grain="30"/>
            <sliver_type name="iotlab-exclusive"/>
        </node>
        <lease slice_id="urn:publicid:IDN+onelab:inria+slice+test_iotlab"
               start_time="1427792428" duration="29">
            <node component_id=
                "urn:publicid:IDN+iotlab+node+m3-10.grenoble.iot-lab.info"/>
        </lease>
        ...
        </rspec>

        """
        # pylint:disable=R0914,W0212
        logger.warning("iotlabaggregate describe")
        logger.warning("iotlabaggregate describe urns : %s" % urns)
        if not options:
            options = {}
        version_manager = VersionManager()
        version = version_manager.get_version(version)
        rspec_version = version_manager._get_version(version.type, version.version, "manifest")
        rspec = RSpec(version=rspec_version, user_options=options)
        xrn = Xrn(urns[0])
        geni_slivers = []

        nodes = self.driver.shell.get_nodes()
        reserved_nodes = self.driver.shell.get_reserved_nodes()
        if not "error" in nodes and not "error" in reserved_nodes:
            # find OAR jobs id for one slice in SFA database
            db_leases = [
                (lease.job_id, lease.slice_hrn)
                for lease in self.driver.api.dbsession().query(LeaseTable).filter(LeaseTable.slice_hrn == xrn.hrn).all()
            ]

            leases = []
            for job_id, slice_hrn in db_leases:
                # OAR job terminated, we delete entry in database
                if not job_id in reserved_nodes:
                    self._delete_db_lease(job_id)
                else:
                    # onelab slice = job submission from OneLAB
                    lease = reserved_nodes[job_id]
                    lease["slice_id"] = hrn_to_urn(slice_hrn, "slice")
                    leases.append(lease)

            # get slivers
            slivers = self.get_slivers(urns, leases, nodes)
            if slivers:
                date = utcparse(slivers[0]["expires"])
                rspec_expires = datetime_to_string(date)
            else:
                rspec_expires = datetime_to_string(utcparse(time.time()))
            rspec.xml.set("expires", rspec_expires)

            rspec_nodes = []

            for sliver in slivers:
                rspec_node = self.sliver_to_rspec_node(sliver)
                rspec_nodes.append(rspec_node)
                geni_sliver = self.rspec_node_to_geni_sliver(rspec_node)
                geni_slivers.append(geni_sliver)
            logger.warning("iotlabaggregate describe geni_slivers %s" % geni_slivers)
            rspec.version.add_nodes(rspec_nodes)

            rspec_leases = self.leases_to_rspec_leases(leases)
            logger.warning("iotlabaggregate describe rspec_leases %s" % rspec_leases)
            rspec.version.add_leases(rspec_leases)

        return {"geni_urn": urns[0], "geni_rspec": rspec.toxml(), "geni_slivers": geni_slivers}
예제 #40
0
    def list_resources(self, version=None, options=None):
        """
        list_resources method sends a RSpec with all Iot-LAB testbed nodes
        and leases (OAR job submission). For leases we get all OAR jobs with
        state Waiting or Running. If we have an entry in SFA database
        (lease table) with OAR job id this submission was launched by SFA
        driver, otherwise it was launched by Iot-LAB Webportal or CLI-tools

        :Example:
        <rspec>
        ...
        <node component_manager_id="urn:publicid:IDN+iotlab+authority+sa"
              component_id=
                  "urn:publicid:IDN+iotlab+node+m3-10.devgrenoble.iot-lab.info"
              exclusive="true" component_name="m3-10.devgrenoble.iot-lab.info">
            <hardware_type name="iotlab-node"/>
            <location country="France"/>
            <granularity grain="60"/>
            ...
        </node>
        ...
        <lease slice_id="urn:publicid:IDN+onelab:inria+slice+test_iotlab"
            start_time="1427792400" duration="30">
            <node component_id=
                "urn:publicid:IDN+iotlab+node+m3-10.grenoble.iot-lab.info"/>
        </lease>
        ...
        </rspec>
        """
        # pylint:disable=R0914,W0212
        logger.warning("iotlabaggregate list_resources")
        logger.warning("iotlabaggregate list_resources options %s" % options)
        if not options:
            options = {}

        version_manager = VersionManager()
        version = version_manager.get_version(version)
        rspec_version = version_manager._get_version(version.type, version.version, "ad")
        rspec = RSpec(version=rspec_version, user_options=options)

        nodes = self.driver.shell.get_nodes()
        reserved_nodes = self.driver.shell.get_reserved_nodes()
        if not "error" in nodes and not "error" in reserved_nodes:
            # convert nodes to rspec nodes
            rspec_nodes = []
            for node in nodes:
                rspec_node = self.node_to_rspec_node(nodes[node])
                rspec_nodes.append(rspec_node)
            rspec.version.add_nodes(rspec_nodes)

            leases = []
            db_leases = {}
            # find OAR jobs id for all slices in SFA database
            for lease in self.driver.api.dbsession().query(LeaseTable).all():
                db_leases[lease.job_id] = lease.slice_hrn

            for lease_id in reserved_nodes:
                # onelab slice = job submission from OneLAB
                if lease_id in db_leases:
                    reserved_nodes[lease_id]["slice_id"] = hrn_to_urn(db_leases[lease_id], "slice")
                # iotlab slice = job submission from Iot-LAB
                else:
                    reserved_nodes[lease_id]["slice_id"] = hrn_to_urn(
                        self.driver.root_auth + "." + reserved_nodes[lease_id]["owner"] + "_slice", "slice"
                    )
                leases.append(reserved_nodes[lease_id])

            rspec_leases = self.leases_to_rspec_leases(leases)
            logger.warning("iotlabaggregate list_resources rspec_leases  %s" % rspec_leases)
            rspec.version.add_leases(rspec_leases)
        return rspec.toxml()