Cleaning and documenting Iotlab files.
authorSandrine Avakian <sandrine.avakian@inria.fr>
Wed, 18 Dec 2013 14:04:00 +0000 (15:04 +0100)
committerSandrine Avakian <sandrine.avakian@inria.fr>
Wed, 18 Dec 2013 14:04:00 +0000 (15:04 +0100)
sfa/importer/iotlabimporter.py
sfa/iotlab/iotlabaggregate.py
sfa/iotlab/iotlabdriver.py
sfa/iotlab/iotlabpostgres.py
sfa/iotlab/iotlabshell.py
sfa/iotlab/iotlabslices.py
sfa/iotlab/iotlabxrn.py

index c29457c..17891cf 100644 (file)
@@ -71,7 +71,7 @@ class IotlabImporter:
 
 
 
-    def exists(self, tablename, engine):
+    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.
@@ -518,11 +518,9 @@ class IotlabImporter:
         #No slice update upon import in iotlab
         else:
             # xxx update the record ...
-            self.logger.warning("Slice update not yet implemented")
-            pass
-        # record current users affiliated with the slice
-
+            self.logger.warning("Iotlab Slice update not implemented")
 
+        # record current users affiliated with the slice
         slice_record.reg_researchers = [user_record]
         try:
             global_dbsession.commit()
@@ -549,7 +547,7 @@ class IotlabImporter:
         # leases_db = TestbedAdditionalSfaDB(config)
         #Create special slice table for iotlab
 
-        if not self.exists('lease_table', engine):
+        if not self.exists('lease_table'):
             init_tables(engine)
             self.logger.info("IotlabImporter.run:  lease_table table created ")
 
index 7ada108..25b1445 100644 (file)
@@ -367,7 +367,8 @@ class IotlabAggregate:
         :param sliver_allocations: dictionary of slivers
         :type sliver_allocations: dict
 
-        :returns: Node dictionary with all necessary data. .
+        :returns: Node dictionary with all necessary data.
+
         .. seealso:: node_to_rspec_node
         """
         rspec_node = self.node_to_rspec_node(sliver)
index 13344aa..0e0af78 100644 (file)
@@ -66,7 +66,8 @@ class IotlabDriver(Driver):
         existing_records = {}
         existing_hrns_by_types = {}
         logger.debug("IOTLAB_API \tGetPeers peer_filter %s " % (peer_filter))
-        all_records = self.api.dbsession().query(RegRecord).filter(RegRecord.type.like('%authority%')).all()
+        query = self.api.dbsession().query(RegRecord)
+        all_records = query.filter(RegRecord.type.like('%authority%')).all()
 
         for record in all_records:
             existing_records[(record.hrn, record.type)] = record
@@ -227,6 +228,7 @@ class IotlabDriver(Driver):
 
         #Only one entry for one user  = one slice in testbed_xp table
         #slicerec = dbsession.query(RegRecord).filter_by(hrn = slice_filter).first()
+
         raw_slicerec = self.api.dbsession().query(RegSlice).options(joinedload('reg_researchers')).filter_by(hrn=slice_filter).first()
         #raw_slicerec = self.api.dbsession().query(RegRecord).filter_by(hrn = slice_filter).first()
         if raw_slicerec:
@@ -612,16 +614,17 @@ class IotlabDriver(Driver):
             logger.debug("IOTLAB_API \tGetLeases  \
                     \r\n leasefilter %s" % ( lease_filter_dict))
 
-            filter_dict_functions = {
-            'slice_hrn' : IotlabShell.filter_lease_name,
-            't_from' : IotlabShell.filter_lease_start_time
-            }
+            filter_dict_functions = {
+            'slice_hrn' : IotlabShell.filter_lease_name,
+            't_from' : IotlabShell.filter_lease_start_time
+            }
             reservation_list = list(unfiltered_reservation_list)
             for filter_type in lease_filter_dict:
                 logger.debug("IOTLAB_API \tGetLeases reservation_list %s" \
                     % (reservation_list))
-                reservation_list = filter_dict_functions[filter_type](\
-                    reservation_list,lease_filter_dict[filter_type] )
+                reservation_list = self.testbed_shell.filter_lease(
+                        reservation_list,filter_type,
+                        lease_filter_dict[filter_type] )
 
                 # Filter the reservation list with a maximum timespan so that the
                 # leases and jobs running after this timestamp do not appear
@@ -678,7 +681,8 @@ class IotlabDriver(Driver):
             kept_experiments)
         deleted_experiments = list(deleted_experiments)
         if len(deleted_experiments) > 0:
-            self.api.dbsession().query(LeaseTableXP).filter(LeaseTableXP.experiment_id.in_(deleted_experiments)).delete(synchronize_session='fetch')
+            request = self.api.dbsession().query(LeaseTableXP)
+            request.filter(LeaseTableXP.experiment_id.in_(deleted_experiments)).delete(synchronize_session='fetch')
             self.api.dbsession().commit()
         return
     def AddSlice(self, slice_record, user_record):
@@ -833,7 +837,7 @@ class IotlabDriver(Driver):
                     recslice.update(
                         {'PI': [recuser['hrn']],
                          'researcher': [recuser['hrn']],
-                         'name': record['hrn'],
+                         'name': recuser['hrn'],
                          'node_ids': [],
                          'oar_job_id': [],
                          'person_ids': [recuser['record_id']]})
@@ -1160,73 +1164,7 @@ class IotlabDriver(Driver):
                  'geni_expires': datetime_to_string(utcparse(sliver['expires']))})
         return geni_slivers
 
-    # def list_resources (self, slice_urn, slice_hrn, creds, options):
-    #     """
-
-    #     List resources from the iotlab aggregate and returns a Rspec
-    #         advertisement with resources found when slice_urn and slice_hrn are
-    #         None (in case of resource discovery).
-    #         If a slice hrn and urn are provided, list experiment's slice
-    #         nodes in a rspec format. Answer to ListResources.
-    #         Caching unused.
-
-    #     :param slice_urn: urn of the slice
-    #     :param slice_hrn: name of the slice
-    #     :param creds: slice credenials
-    #     :type slice_urn: string
-    #     :type slice_hrn: string
-    #     :type creds: ? unused
-    #     :param options: options used when listing resources (list_leases, info,
-    #         geni_available)
-    #     :returns: rspec string in xml
-    #     :rtype: string
-
-    #     .. note:: creds are unused
-    #     """
-
-    #     #cached_requested = options.get('cached', True)
-
-    #     version_manager = VersionManager()
-    #     # get the rspec's return format from options
-    #     rspec_version = \
-    #         version_manager.get_version(options.get('geni_rspec_version'))
-    #     version_string = "rspec_%s" % (rspec_version)
-
-    #     #panos adding the info option to the caching key (can be improved)
-    #     if options.get('info'):
-    #         version_string = version_string + "_" + \
-    #             options.get('info', 'default')
-
-    #     # Adding the list_leases option to the caching key
-    #     if options.get('list_leases'):
-    #         version_string = version_string + "_" + \
-    #         options.get('list_leases', 'default')
-
-    #     # Adding geni_available to caching key
-    #     if options.get('geni_available'):
-    #         version_string = version_string + "_" + \
-    #             str(options.get('geni_available'))
-
-    #     # look in cache first
-    #     #if cached_requested and self.cache and not slice_hrn:
-    #         #rspec = self.cache.get(version_string)
-    #         #if rspec:
-    #             #logger.debug("IotlabDriver.ListResources: \
-    #                                 #returning cached advertisement")
-    #             #return rspec
-
-    #     #panos: passing user-defined options
-    #     aggregate = IotlabAggregate(self)
-
-    #     rspec = aggregate.get_rspec(slice_xrn=slice_urn,
-    #                                 version=rspec_version, options=options)
-
-    #     # cache the result
-    #     #if self.cache and not slice_hrn:
-    #         #logger.debug("Iotlab.ListResources: stores advertisement in cache")
-    #         #self.cache.add(version_string, rspec)
-
-    #     return rspec
+
 
 
     def list_slices(self, creds, options):
@@ -1309,7 +1247,7 @@ class IotlabDriver(Driver):
 
         TODO: needs review
         .. warning:: SA 12/12/13 - Removed. should be done in iotlabimporter
-            since users, keys and slice are managed by the LDAP.
+        since users, keys and slice are managed by the LDAP.
 
         """
         # pointer = old_sfa_record['pointer']
@@ -1497,7 +1435,7 @@ class IotlabDriver(Driver):
         # requested_attributes = rspec.version.get_slice_attributes()
 
         # ensure site record exists
-        # site = slices.verify_site(xrn.hrn, slice_record, peer, sfa_peer, options=options)
+
         # ensure slice record exists
 
         current_slice = slices.verify_slice(xrn.hrn, slice_record, sfa_peer)
@@ -1532,7 +1470,8 @@ class IotlabDriver(Driver):
 
         # add/remove leases
         rspec_requested_leases = rspec.version.get_leases()
-        leases = slices.verify_slice_leases(slice_record, requested_xp_dict, peer)
+        leases = slices.verify_slice_leases(slice_record,
+                                                requested_xp_dict, peer)
         logger.debug("IOTLABDRIVER.PY \tallocate leases  %s \
                         rspec_requested_leases %s" % (leases,
                         rspec_requested_leases))
index de74dc9..097e61e 100644 (file)
@@ -1,40 +1,22 @@
 """
-File defining classes to handle the table in the iotlab dedicated database.
+File holding a class to define the table in the iotlab dedicated table.
+The table is the SFA dtabase, therefore all the access mecanism
+(session, engine...) is handled by alchemy.py.
+
+..seealso:: alchemy.py
 """
 
-# from sqlalchemy import create_engine
-# from sqlalchemy.orm import sessionmaker
-# from sfa.util.config import Config
-# from sfa.util.sfalogging import logger
-from sfa.storage.model import Base, AlchemyObj
+from sfa.storage.model import Base
 from sqlalchemy import Column, Integer, String
-# from sqlalchemy import Table, MetaData
-# # from sqlalchemy.ext.declarative import declarative_base
-
-# # from sqlalchemy.dialects import postgresql
-
-# from sqlalchemy.exc import NoSuchTableError
-
-
-#Dict holding the columns names of the table as keys
-#and their type, used for creation of the table
-slice_table = {'record_id_user': 'integer PRIMARY KEY references X ON DELETE \
-                CASCADE ON UPDATE CASCADE', 'oar_job_id': 'integer DEFAULT -1',
-               'record_id_slice': 'integer', 'slice_hrn': 'text NOT NULL'}
-
-#Dict with all the specific iotlab tables
-# tablenames_dict = {'lease_table': slice_table}
 
 
-# TestbedBase = declarative_base()
 
-
-# class LeaseTableXP (TestbedBase):
-# class LeaseTableXP (Base,AlchemyObj):
 class LeaseTableXP (Base):
-    """ SQL alchemy class to manipulate the rows of the slice_iotlab table in
-    lease_table database. Handles the records representation and creates the
-    table if it does not exist yet.
+    """ SQL alchemy class to manipulate the rows of the lease_table table in the
+    SFA database. Handles the records representation and creates.
+    Table creation is made by the importer if it is not in the database yet.
+
+    .. seealso:: init_tables in model.py, run in iotlabimporter.py
 
     """
     __tablename__ = 'lease_table'
@@ -45,7 +27,7 @@ class LeaseTableXP (Base):
 
     def __init__(self, slice_hrn=None, experiment_id=None,  end_time=None):
         """
-        Defines a row of the slice_iotlab table
+        Defines a row of the lease_table table
         """
         if slice_hrn:
             self.slice_hrn = slice_hrn
@@ -58,218 +40,8 @@ class LeaseTableXP (Base):
         """Prints the SQLAlchemy record to the format defined
         by the function.
         """
-        result = "<lease_table : slice_hrn = %s , experiment_id %s end_time = %s" \
-            % (self.slice_hrn, self.experiment_id, self.end_time)
+        result = "<lease_table : slice_hrn = %s , experiment_id %s \
+            end_time = %s" % (self.slice_hrn, self.experiment_id,
+            self.end_time)
         result += ">"
         return result
-
-
-# class TestbedAdditionalSfaDB(object):
-#     """ SQL Alchemy connection class.
-#     From alchemy.py
-#     """
-#     # Stores the unique Singleton instance-
-#     _connection_singleton = None
-#     # defines the database name
-#     dbname = "testbed_xp"
-
-#     class Singleton:
-#         """
-#         Class used with this Python singleton design pattern to allow the
-#         definition of one single instance of iotlab db session in the whole
-#         code. Wherever a conenction to the database is needed, this class
-#         returns the same instance every time. Removes the need for global
-#         variable throughout the code.
-#         """
-
-#         def __init__(self, config, debug=False):
-#             self.testbed_engine = None
-#             self.testbed_session = None
-#             self.url = None
-#             self.create_testbed_engine(config, debug)
-#             self.session()
-
-#         def create_testbed_engine(self, config, debug=False):
-#             """Creates the SQLAlchemy engine, which is the starting point for
-#             any SQLAlchemy application.
-#             :param config: configuration object created by SFA based on the
-#             configuration file in /etc
-#             :param debug: if set to true, echo and echo pool will be set to true
-#             as well. If echo is True, all statements as well as a repr() of
-#             their parameter lists to the engines logger, which defaults to
-#             sys.stdout. If echo_pool is True, the connection pool will log all
-#             checkouts/checkins to the logging stream. A python logger can be
-#             used to configure this logging directly but so far it has not been
-#             configured. Refer to sql alchemy engine documentation.
-
-#             :type config: Config instance (sfa.util.config)
-#             :type debug: bool
-
-#             """
-
-#             if debug is True:
-#                 l_echo_pool = True
-#                 l_echo = True
-#             else:
-#                 l_echo_pool = False
-#                 l_echo = False
-#              # the former PostgreSQL.py used the psycopg2 directly and was doing
-#             #self.connection.set_client_encoding("UNICODE")
-#             # it's unclear how to achieve this in sqlalchemy, nor if it's needed
-#             # at all
-#             # http://www.sqlalchemy.org/docs/dialects/postgresql.html#unicode
-#             # we indeed have /var/lib/pgsql/data/postgresql.conf where
-#             # this setting is unset, it might be an angle to tweak that if need
-#             # be try a unix socket first
-#             #  - omitting the hostname does the trick
-#             unix_url = "postgresql+psycopg2://%s:%s@:%s/%s" \
-#                 % (config.SFA_DB_USER, config.SFA_DB_PASSWORD,
-#                    config.SFA_DB_PORT, TestbedAdditionalSfaDB.dbname)
-
-#             # the TCP fallback method
-#             tcp_url = "postgresql+psycopg2://%s:%s@%s:%s/%s" \
-#                 % (config.SFA_DB_USER, config.SFA_DB_PASSWORD,
-#                     config.SFA_DB_HOST, config.SFA_DB_PORT, TestbedAdditionalSfaDB.dbname)
-
-#             for url in [unix_url, tcp_url]:
-#                 try:
-#                     self.testbed_engine = create_engine(
-#                         url, echo_pool=l_echo_pool, echo=l_echo)
-#                     self.check()
-#                     self.url = url
-#                     return
-#                 except:
-#                     pass
-#                 self.testbed_engine = None
-
-#             raise Exception("Could not connect to database")
-
-#         def check(self):
-#             """ Check if a table exists by trying a selection
-#             on the table.
-
-#             """
-#             self.testbed_engine.execute("select 1").scalar()
-
-
-#         def session(self):
-#             """
-#             Creates a SQLalchemy session. Once the session object is created
-#             it should be used throughout the code for all the operations on
-#             tables for this given database.
-
-#             """
-#             if self.testbed_session is None:
-#                 Session = sessionmaker()
-#                 self.testbed_session = Session(bind=self.testbed_engine)
-#             return self.testbed_session
-
-#         def close_session(self):
-#             """
-#             Closes connection to database.
-
-#             """
-#             if self.testbed_session is None:
-#                 return
-#             self.testbed_session.close()
-#             self.testbed_session = None
-
-
-        # def update_experiments_in_additional_sfa_db(self,
-        #     experiment_list_from_testbed, experiment_list_in_db):
-        #     """ Cleans the iotlab db by deleting expired and cancelled jobs.
-
-        #     Compares the list of experiment ids given by the testbed with the
-        #     experiment ids that are already in the database, deletes the
-        #     experiments that are no longer in the testbed experiment id list.
-
-        #     :param  experiment_list_from_testbed: list of experiment ids coming
-        #         from testbed
-        #     :type experiment_list_from_testbed: list
-        #     :param experiment_list_in_db: list of experiment ids from the sfa
-        #         additionnal database.
-        #     :type experiment_list_in_db: list
-
-        #     :returns: None
-        #     """
-        #     #Turn the list into a set
-        #     set_experiment_list_in_db = set(experiment_list_in_db)
-
-        #     kept_experiments = set(experiment_list_from_testbed).intersection(set_experiment_list_in_db)
-        #     logger.debug("\r\n \t update_experiments_in_additional_sfa_db \
-        #                     experiment_list_in_db %s \r\n \
-        #                     experiment_list_from_testbed %s \
-        #                     kept_experiments %s "
-        #                  % (set_experiment_list_in_db,
-        #                   experiment_list_from_testbed, kept_experiments))
-        #     deleted_experiments = set_experiment_list_in_db.difference(
-        #         kept_experiments)
-        #     deleted_experiments = list(deleted_experiments)
-        #     if len(deleted_experiments) > 0:
-        #         self.testbed_session.query(LeaseTableXP).filter(LeaseTableXP.experiment_id.in_(deleted_experiments)).delete(synchronize_session='fetch')
-        #         self.testbed_session.commit()
-        #     return
-
-    # def __init__(self, config, debug=False):
-    #     self.sl_base = TestbedBase
-
-    #      # Check whether we already have an instance
-    #     if TestbedAdditionalSfaDB._connection_singleton is None:
-    #         TestbedAdditionalSfaDB._connection_singleton = \
-    #             TestbedAdditionalSfaDB.Singleton(config, debug)
-
-    #     # Store instance reference as the only member in the handle
-    #     self._EventHandler_singleton = \
-    #         TestbedAdditionalSfaDB._connection_singleton
-
-    # def __getattr__(self, aAttr):
-    #     """
-    #     Delegate access to implementation.
-
-    #     :param aAttr: Attribute wanted.
-    #     :returns: Attribute
-    #     """
-    #     return getattr(self._connection_singleton, aAttr)
-
-
-
-    # # def __setattr__(self, aAttr, aValue):
-    # #     """Delegate access to implementation.
-
-    # #      :param attr: Attribute wanted.
-    # #      :param value: Vaule to be set.
-    # #      :return: Result of operation.
-    # #      """
-    # #     return setattr(self._connection_singleton, aAttr, aValue)
-
-    # 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.testbed_engine)
-    #     try:
-    #         table = Table(tablename, metadata, autoload=True)
-    #         return True
-
-    #     except NoSuchTableError:
-    #         logger.log_exc("SLABPOSTGRES tablename %s does not exist"
-    #                        % (tablename))
-    #         return False
-
-    # def createtable(self):
-    #     """
-    #     Creates all the table sof the engine.
-    #     Uses the global dictionnary holding the tablenames and the table schema.
-
-    #     """
-
-    #     logger.debug("IOTLABPOSTGRES createtable \
-    #                 TestbedBase.metadata.sorted_tables %s \r\n engine %s"
-    #                  % (TestbedBase.metadata.sorted_tables, self.testbed_engine))
-    #     TestbedBase.metadata.create_all(self.testbed_engine)
-    #     return
index 406bed9..ba62ca9 100644 (file)
@@ -2,22 +2,15 @@
 File containing the IotlabShell, used to interact with nodes, users,
 slices, leases and keys,  as well as the dedicated iotlab database and table,
 holding information about which slice is running which job.
-TODO: Remove interactons with the SFA DB and put it in the driver iotlabdriver
-instead.
 
 """
 from datetime import datetime
 
 from sfa.util.sfalogging import logger
 
-
-from sfa.iotlab.iotlabpostgres import LeaseTableXP
 from sfa.iotlab.OARrestapi import OARrestapi
 from sfa.iotlab.LDAPapi import LDAPapi
 
-from sfa.util.xrn import Xrn, hrn_to_urn, get_authority
-
-from sfa.iotlab.iotlabxrn import xrn_object
 
 class IotlabShell():
     """ Class enabled to use LDAP and OAR api calls. """
@@ -210,9 +203,13 @@ class IotlabShell():
         #Get job resources list from OAR
         node_id_list = self.oar.parser.SendRequest(req, job_id, username)
         logger.debug("IOTLAB_API \t GetJobsResources  %s " %(node_id_list))
-
+        resources = self.GetNodes()
+        oar_id_node_dict = {}
+        for node in resources:
+            oar_id_node_dict[node['oar_id']] = node['hostname']
         hostname_list = \
-            self.__get_hostnames_from_oar_node_ids(node_id_list)
+            self.__get_hostnames_from_oar_node_ids(oar_id_node_dict,
+                                                            node_id_list)
 
 
         #Replaces the previous entry "assigned_network_address" /
@@ -229,7 +226,8 @@ class IotlabShell():
         """
         return self.oar.parser.SendRequest("GET_running_jobs")
 
-    def __get_hostnames_from_oar_node_ids(self, oar_id_node_dict,
+    @staticmethod
+    def __get_hostnames_from_oar_node_ids(oar_id_node_dict,
             resource_id_list ):
         """Get the hostnames of the nodes from their OAR identifiers.
         Get the list of nodes dict using GetNodes and find the hostname
@@ -674,77 +672,71 @@ class IotlabShell():
 
 
     @staticmethod
-    def filter_lease_name(reservation_list, filter_value):
+    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))
-        for reservation in reservation_list:
-            if 'slice_hrn' in reservation and \
-                reservation['slice_hrn'] != filter_value:
-                filtered_reservation_list.remove(reservation)
+        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))
 
-        logger.debug("IOTLAB_API \t filter_lease_name filtered_reservation_list\
-                     %s" % (filtered_reservation_list))
         return filtered_reservation_list
 
-    @staticmethod
-    def filter_lease_start_time(reservation_list, filter_value):
-        filtered_reservation_list = list(reservation_list)
+    # @staticmethod
+    # def filter_lease_start_time(reservation_list, timespan):
+    #     """Filters the lease reservation list by removing each lease whose
+    #     slice_hrn is not the wanted_slice provided. Returns the list of leases
+    #     in one slice (wanted_slice).
 
-        for reservation in reservation_list:
-            if 't_from' in reservation and \
-                reservation['t_from'] > filter_value:
-                filtered_reservation_list.remove(reservation)
+    #     """
+    #     filtered_reservation_list = list(reservation_list)
 
-        return filtered_reservation_list
+    #     for reservation in reservation_list:
+    #         if 't_from' in reservation and \
+    #             reservation['t_from'] > timespan:
+    #             filtered_reservation_list.remove(reservation)
 
+    #     return filtered_reservation_list
 
 
 
 
 
-#TODO FUNCTIONS SECTION 04/07/2012 SA
-
-    ##TODO : Is UnBindObjectFromPeer still necessary ? Currently does nothing
-    ##04/07/2012 SA
-    #@staticmethod
-    #def UnBindObjectFromPeer( auth, object_type, object_id, shortname):
-        #""" This method is a hopefully temporary hack to let the sfa correctly
-        #detach the objects it creates from a remote peer object. This is
-        #needed so that the sfa federation link can work in parallel with
-        #RefreshPeer, as RefreshPeer depends on remote objects being correctly
-        #marked.
-        #Parameters:
-        #auth : struct, API authentication structure
-            #AuthMethod : string, Authentication method to use
-        #object_type : string, Object type, among 'site','person','slice',
-        #'node','key'
-        #object_id : int, object_id
-        #shortname : string, peer shortname
-        #FROM PLC DOC
-
-        #"""
-        #logger.warning("IOTLAB_API \tUnBindObjectFromPeer EMPTY-\
-                        #DO NOTHING \r\n ")
-        #return
 
-    ##TODO Is BindObjectToPeer still necessary ? Currently does nothing
-    ##04/07/2012 SA
-    #|| Commented out 28/05/13 SA
-    #def BindObjectToPeer(self, auth, object_type, object_id, shortname=None, \
-                                                    #remote_object_id=None):
-        #"""This method is a hopefully temporary hack to let the sfa correctly
-        #attach the objects it creates to a remote peer object. This is needed
-        #so that the sfa federation link can work in parallel with RefreshPeer,
-        #as RefreshPeer depends on remote objects being correctly marked.
-        #Parameters:
-        #shortname : string, peer shortname
-        #remote_object_id : int, remote object_id, set to 0 if unknown
-        #FROM PLC API DOC
+#TODO FUNCTIONS SECTION 04/07/2012 SA
 
-        #"""
-        #logger.warning("IOTLAB_API \tBindObjectToPeer EMPTY - DO NOTHING \r\n ")
-        #return
 
     ##TODO UpdateSlice 04/07/2012 SA || Commented out 28/05/13 SA
     ##Funciton should delete and create another job since oin iotlab slice=job
index f5ebfa7..c441d65 100644 (file)
@@ -133,7 +133,8 @@ class IotlabSlices:
             job['duration'] = \
                 str(int(job['duration']) \
                 * self.driver.testbed_shell.GetLeaseGranularity())
-            if job['duration'] < self.driver.testbed_shell.GetLeaseGranularity():
+            if job['duration'] < \
+                    self.driver.testbed_shell.GetLeaseGranularity():
                 del requested_jobs_dict[job['start_time']]
 
         #Requested jobs
@@ -313,7 +314,7 @@ class IotlabSlices:
         if slices_list:
             for sl in slices_list:
 
-                logger.debug("SLABSLICE \t verify_slice slicename %s \
+                logger.debug("IOTLABSLICES \t verify_slice slicename %s \
                                 slices_list %s sl %s \r slice_record %s"
                              % (slicename, slices_list, sl, slice_record))
                 sfa_slice = sl
@@ -338,7 +339,8 @@ class IotlabSlices:
                          }
 
             if ldap_user:
-                hrn = self.driver.testbed_shell.root_auth + '.' + ldap_user['uid']
+                hrn = self.driver.testbed_shell.root_auth + '.' \
+                                                + ldap_user['uid']
                 user = self.driver.get_user_record(hrn)
 
                 logger.debug(" IOTLABSLICES \tverify_slice hrn %s USER %s"
@@ -354,7 +356,7 @@ class IotlabSlices:
 
     def verify_persons(self, slice_hrn, slice_record, users, options={}):
         """Ensures the users in users list exist and are enabled in LDAP. Adds
-        person if needed.
+        person if needed (AddPerson).
 
         Checking that a user exist is based on the user's email. If the user is
         still not found in the LDAP, it means that the user comes from another
@@ -366,8 +368,8 @@ class IotlabSlices:
         :param slice_record: record of the slice_hrn
         :param users: users is a record list. Records can either be
             local records or users records from known and trusted federated
-            sites.If the user is from another site that iotlab doesn't trust yet,
-            then Resolve will raise an error before getting to create_sliver.
+            sites.If the user is from another site that iotlab doesn't trust
+            yet, then Resolve will raise an error before getting to allocate.
 
         :type slice_hrn: string
         :type slice_record: string
@@ -378,7 +380,6 @@ class IotlabSlices:
 
 
         """
-        #TODO SA 21/08/12 verify_persons Needs review
 
         logger.debug("IOTLABSLICES \tverify_persons \tslice_hrn  %s  \
                     \t slice_record %s\r\n users %s \t  "
@@ -400,7 +401,7 @@ class IotlabSlices:
                 users_by_email[info['email']] = info
                 users_dict[info['email']] = info
 
-        logger.debug("SLABSLICE.PY \t verify_person  \
+        logger.debug("IOTLABSLICES.PY \t verify_person  \
                         users_dict %s \r\n user_by_email %s \r\n  "
                      % (users_dict, users_by_email))
 
@@ -443,28 +444,28 @@ class IotlabSlices:
                 ldap_reslt = self.driver.testbed_shell.ldap.LdapSearch(req)
 
                 if ldap_reslt:
-                    logger.debug(" SLABSLICE.PY \tverify_person users \
+                    logger.debug(" IOTLABSLICES.PY \tverify_person users \
                                 USER already in Iotlab \t ldap_reslt %s \
                                 " % (ldap_reslt))
                     existing_users.append(ldap_reslt[1])
 
                 else:
                     #User not existing in LDAP
-                    logger.debug("SLABSLICE.PY \tverify_person users \
+                    logger.debug("IOTLABSLICES.PY \tverify_person users \
                                 not in ldap ...NEW ACCOUNT NEEDED %s \r\n \t \
                                 ldap_reslt %s " % (users, ldap_reslt))
 
         requested_user_emails = users_by_email.keys()
         requested_user_hrns = \
             [users_by_email[user]['hrn'] for user in users_by_email]
-        logger.debug("SLABSLICE.PY \tverify_person  \
+        logger.debug("IOTLABSLICES.PY \tverify_person  \
                        users_by_email  %s " % (users_by_email))
 
         #Check that the user of the slice in the slice record
         #matches one of the existing users
         try:
             if slice_record['reg-researchers'][0] in requested_user_hrns:
-                logger.debug(" SLABSLICE  \tverify_person ['PI']\
+                logger.debug(" IOTLABSLICES  \tverify_person ['PI']\
                                 slice_record %s" % (slice_record))
 
         except KeyError:
@@ -487,7 +488,7 @@ class IotlabSlices:
         #requested_user_email is in existing_user_emails
         if len(added_user_emails) == 0:
             slice_record['login'] = users_dict[requested_user_emails[0]]['uid']
-            logger.debug(" SLABSLICE  \tverify_person QUICK DIRTY %s"
+            logger.debug(" IOTLABSLICES  \tverify_person QUICK DIRTY %s"
                          % (slice_record))
 
         for added_user_email in added_user_emails:
@@ -515,7 +516,7 @@ class IotlabSlices:
                 # error message in ret
                 logger.debug(" IOTLABSLICES ret message %s" %(ret))
 
-            logger.debug(" SLABSLICE \r\n \r\n  \t THE SECOND verify_person\
+            logger.debug(" IOTLABSLICES \r\n \r\n  \t THE SECOND verify_person\
                            person %s" % (person))
             #Update slice_Record with the id now known to LDAP
 
@@ -570,12 +571,6 @@ class IotlabSlices:
                                             #key['key_id'], peer['shortname'], \
                                             #remote_key_id)
 
-                    #finally:
-                        #if peer:
-                            #self.driver.testbed_shell.BindObjectToPeer('person', \
-                                    #person['person_id'], peer['shortname'], \
-                                    #user['person_id'])
-
         # remove old keys (only if we are not appending)
         append = options.get('append', True)
         if append is False:
index c7a147c..bae7036 100644 (file)
@@ -1,4 +1,5 @@
-# specialized Xrn class for Dummy TB
+""" specialized Xrn class for Iotlab. SA
+"""
 import re
 from sfa.util.xrn import Xrn
 
@@ -31,31 +32,59 @@ def xrn_object(root_auth, hostname):
 
 # temporary helper functions to use this module instead of namespace
 def hostname_to_hrn (auth, hostname):
-    return IotlabXrn(auth=auth ,hostname=hostname).get_hrn()
+    """Turns node hostname into hrn.
+    :param auth: Site authority.
+    :type auth: string
+    :param hostname: Node hostname.
+    :type hostname: string.
+
+    :returns: Node's hrn.
+    :rtype: string
+    """
+    return IotlabXrn(auth=auth, hostname=hostname).get_hrn()
+
 def hostname_to_urn(auth, hostname):
-    return IotlabXrn(auth=auth,hostname=hostname).get_urn()
-def slicename_to_hrn (auth_hrn, slicename):
-    return IotlabXrn(auth=auth_hrn,slicename=slicename).get_hrn()
+    """Turns node hostname into urn.
+    :param auth: Site authority.
+    :type auth: string
+    :param hostname: Node hostname.
+    :type hostname: string.
 
-def hrn_to_iotlab_slicename (hrn):
-    return IotlabXrn(xrn=hrn,type='slice').iotlab_slicename()
-def hrn_to_iotlab_authname (hrn):
-    return IotlabXrn(xrn=hrn,type='any').iotlab_authname()
+    :returns: Node's urn.
+    :rtype: string
+    """
+    return IotlabXrn(auth=auth, hostname=hostname).get_urn()
 
+# def slicename_to_hrn (auth_hrn, slicename):
+    # return IotlabXrn(auth=auth_hrn, slicename=slicename).get_hrn()
+
+# def hrn_to_iotlab_slicename (hrn):
+#     return IotlabXrn(xrn=hrn, type='slice').iotlab_slicename()
+
+# def hrn_to_iotlab_authname (hrn):
+#     return IotlabXrn(xrn=hrn, type='any').iotlab_authname()
 
-class IotlabXrn (Xrn):
 
+class IotlabXrn (Xrn):
+    """
+    Defines methods to turn a hrn/urn into a urn/hrn, or to get the name
+    of the slice/user from the hrn.
+    """
     @staticmethod
     def site_hrn (auth):
+        """Returns the site hrn, which is also the testbed authority in
+            iotlab/cortexlab.
+        """
         return auth
 
-    def __init__ (self, auth=None, hostname=None, login=None, slicename=None,**kwargs):
+    def __init__ (self, auth=None, hostname=None, login=None,
+                                            slicename=None, **kwargs):
         #def hostname_to_hrn(auth_hrn, login_base, hostname):
         if hostname is not None:
-            self.type ='node'
+            self.type = 'node'
             # keep only the first part of the DNS name
             # escape the '.' in the hostname
-            self.hrn ='.'.join( [auth, Xrn.escape(hostname)] )
+            self.hrn = '.'.join( [auth, Xrn.escape(hostname)] )
             self.hrn_to_urn()
 
         elif login is not None:
@@ -64,17 +93,23 @@ class IotlabXrn (Xrn):
             self.hrn_to_urn()
         #def slicename_to_hrn(auth_hrn, slicename):
         elif slicename is not None:
-            self.type ='slice'
+            self.type = 'slice'
             slicename = '_'.join([login, "slice"])
             self.hrn = '.'.join([auth, slicename])
             self.hrn_to_urn()
             # split at the first _
 
         else:
-            Xrn.__init__ (self,**kwargs)
+            Xrn.__init__ (self, **kwargs)
+
 
-    #def hrn_to_pl_slicename(hrn):
     def iotlab_slicename (self):
+        """Returns the slice name from an iotlab slice hrn.
+
+        :rtype: string
+        :returns: slice name.
+        """
+
         self._normalize()
         leaf = self.leaf
         sliver_id_parts = leaf.split(':')
@@ -83,22 +118,22 @@ class IotlabXrn (Xrn):
         return name
 
     #def hrn_to_pl_authname(hrn):
-    def iotlab_authname (self):
-        self._normalize()
-        return self.authority[-1]
+    def iotlab_authname (self):
+        self._normalize()
+        return self.authority[-1]
 
-    def iotlab_login_base (self):
-        self._normalize()
-        if self.type and self.type.startswith('authority'):
-            base = self.leaf
-        else:
-            base = self.authority[-1]
+    def iotlab_login_base (self):
+        self._normalize()
+        if self.type and self.type.startswith('authority'):
+            base = self.leaf
+        else:
+            base = self.authority[-1]
 
-        # Fix up names of GENI Federates
-        base = base.lower()
-        base = re.sub('\\\[^a-zA-Z0-9]', '', base)
+        # Fix up names of GENI Federates
+        base = base.lower()
+        base = re.sub('\\\[^a-zA-Z0-9]', '', base)
 
-        if len(base) > 20:
-            base = base[len(base)-20:]
+        if len(base) > 20:
+            base = base[len(base)-20:]
 
-        return base
+        return base