SA bug hunt
[sfa.git] / sfa / importer / iotlabimporter.py
1 from sfa.util.config import Config
2 from sfa.util.xrn import Xrn, get_authority, hrn_to_urn
3
4 from sfa.iotlab.iotlabdriver import IotlabDriver
5
6 from sfa.trust.certificate import Keypair, convert_public_key
7 from sfa.trust.gid import create_uuid
8
9 from sfa.storage.alchemy import dbsession
10 from sfa.storage.model import RegRecord, RegAuthority, RegSlice, RegNode, \
11                                                     RegUser, RegKey
12
13
14 from sqlalchemy.exc import SQLAlchemyError
15
16
17
18 <<<<<<< HEAD:sfa/importer/iotlabimporter.py
19 class IotlabImporter:
20     """
21     IotlabImporter class, generic importer_class. Used to populate the SFA DB
22     with iotlab resources' records.
23 =======
24 class SlabImporter:
25     """
26     SlabImporter class, generic importer_class. Used to populate the SFA DB
27     with senslab resources' records.
28 >>>>>>> 3fe7429... SA:sfa/importer/slabimporter.py
29     Used to update records when new resources, users or nodes, are added
30     or deleted.
31     """
32
33     def __init__ (self, auth_hierarchy, loc_logger):
34         """
35         Sets and defines import logger and the authority name. Gathers all the
36         records already registerd in the SFA DB, broke them into 3 dicts,
37         by type and hrn, by email and by type and pointer.
38
39         :param auth_hierarchy: authority name
40         :type auth_hierarchy: string
41         :param loc_logger: local logger
42         :type loc_logger: _SfaLogger
43
44         """
45         self.auth_hierarchy = auth_hierarchy
46         self.logger = loc_logger
47         self.logger.setLevelDebug()
48         #retrieve all existing SFA objects
49         self.all_records = dbsession.query(RegRecord).all()
50
51         # initialize record.stale to True by default,
52         # then mark stale=False on the ones that are in use
53         for record in self.all_records:
54             record.stale = True
55         #create hash by (type,hrn)
56         #used  to know if a given record is already known to SFA
57         self.records_by_type_hrn = \
58             dict([( (record.type,record.hrn), record) \
59                                         for record in self.all_records])
60
61         self.users_rec_by_email = \
62             dict([ (record.email, record) \
63                 for record in self.all_records if record.type == 'user'])
64
65         # create hash by (type,pointer)
66         self.records_by_type_pointer = \
67             dict([ ( (str(record.type), record.pointer) , record) \
68                 for record in self.all_records  if record.pointer != -1])
69
70
71
72     @staticmethod
73     def hostname_to_hrn_escaped(root_auth, hostname):
74         """
75
76         Returns a node's hrn based on its hostname and the root
77         authority and by removing special caracters from the hostname.
78
79         :param root_auth: root authority name
80         :param hostname: nodes's hostname
81         :type  root_auth: string
82         :type hostname: string
83         :rtype: string
84         """
85         return '.'.join( [root_auth, Xrn.escape(hostname)] )
86
87
88     @staticmethod
89     def slicename_to_hrn(person_hrn):
90         """
91
92         Returns the slicename associated to a given person's hrn.
93
94         :param person_hrn: user's hrn
95         :type person_hrn: string
96         :rtype: string
97         """
98         return  (person_hrn +'_slice')
99
100     def add_options (self, parser):
101         # we don't have any options for now
102         pass
103
104     def find_record_by_type_hrn(self, record_type, hrn):
105         """
106
107         Returns the record associated with a given hrn and hrn type.
108         Returns None if the key tuple is not in dictionary.
109
110         :param record_type: the record's type (slice, node, authority...)
111         :type  record_type: string
112         :param hrn: Human readable name of the object's record
113         :type hrn: string
114         :rtype: RegUser if user, RegSlice if slice, RegNode if node...
115                 or None if record does not exist.
116
117         """
118         return self.records_by_type_hrn.get ( (record_type, hrn), None)
119
120     def locate_by_type_pointer (self, record_type, pointer):
121         """
122
123         Returns the record corresponding to the key pointer and record
124         type. Returns None if the record does not exist and is not in the
125         records_by_type_pointer dictionnary.
126
127         :param record_type: the record's type (slice, node, authority...)
128         :type  record_type: string
129         :param pointer:Pointer to where the record is in the origin db,
130         used in case the record comes from a trusted authority.
131         :type pointer: integer
132         :rtype: RegUser if user, RegSlice if slice, RegNode if node...
133                 or None if record does not exist.
134         """
135         return self.records_by_type_pointer.get ( (record_type, pointer), None)
136
137
138     def update_just_added_records_dict (self, record):
139         """
140
141         Updates the records_by_type_hrn dictionnary if the record has
142         just been created.
143
144         :param record: Record to add in the records_by_type_hrn dict.
145         :type record: dictionary
146         """
147         rec_tuple = (record.type, record.hrn)
148         if rec_tuple in self.records_by_type_hrn:
149             self.logger.warning ("IotlabImporter.update_just_added_records_dict:\
150                         duplicate (%s,%s)"%rec_tuple)
151             return
152         self.records_by_type_hrn [ rec_tuple ] = record
153
154 <<<<<<< HEAD:sfa/importer/iotlabimporter.py
155     def import_sites_and_nodes(self, iotlabdriver):
156 =======
157     def import_sites_and_nodes(self, slabdriver):
158 >>>>>>> 3fe7429... SA:sfa/importer/slabimporter.py
159         """
160
161         Gets all the sites and nodes from OAR, process the information,
162         creates hrns and RegAuthority for sites, and feed them to the database.
163         For each site, import the site's nodes to the DB by calling
164         import_nodes.
165
166 <<<<<<< HEAD:sfa/importer/iotlabimporter.py
167         :param iotlabdriver: IotlabDriver object, used to have access to iotlabdriver
168         methods and fetching info on sites and nodes.
169         :type iotlabdriver: IotlabDriver
170         """
171
172         sites_listdict  = iotlabdriver.iotlab_api.GetSites()
173         nodes_listdict  = iotlabdriver.iotlab_api.GetNodes()
174 =======
175         :param slabdriver: SlabDriver object, used to have access to slabdriver
176         methods and fetching info on sites and nodes.
177         :type slabdriver: SlabDriver
178         """
179
180         sites_listdict  = slabdriver.slab_api.GetSites()
181         nodes_listdict  = slabdriver.slab_api.GetNodes()
182 >>>>>>> 3fe7429... SA:sfa/importer/slabimporter.py
183         nodes_by_id = dict([(node['node_id'], node) for node in nodes_listdict])
184         for site in sites_listdict:
185             site_hrn = site['name']
186             site_record = self.find_record_by_type_hrn ('authority', site_hrn)
187             if not site_record:
188                 try:
189                     urn = hrn_to_urn(site_hrn, 'authority')
190                     if not self.auth_hierarchy.auth_exists(urn):
191                         self.auth_hierarchy.create_auth(urn)
192
193                     auth_info = self.auth_hierarchy.get_auth_info(urn)
194                     site_record = RegAuthority(hrn=site_hrn, \
195                                                gid=auth_info.get_gid_object(),
196                                                pointer='-1',
197                                                authority=get_authority(site_hrn))
198                     site_record.just_created()
199                     dbsession.add(site_record)
200                     dbsession.commit()
201 <<<<<<< HEAD:sfa/importer/iotlabimporter.py
202                     self.logger.info("IotlabImporter: imported authority (site) \
203 =======
204                     self.logger.info("SlabImporter: imported authority (site) \
205 >>>>>>> 3fe7429... SA:sfa/importer/slabimporter.py
206                          %s" % site_record)
207                     self.update_just_added_records_dict(site_record)
208                 except SQLAlchemyError:
209                     # if the site import fails then there is no point in
210                     # trying to import the
211                     # site's child records(node, slices, persons), so skip them.
212 <<<<<<< HEAD:sfa/importer/iotlabimporter.py
213                     self.logger.log_exc("IotlabImporter: failed to import site. \
214 =======
215                     self.logger.log_exc("SlabImporter: failed to import site. \
216 >>>>>>> 3fe7429... SA:sfa/importer/slabimporter.py
217                         Skipping child records")
218                     continue
219             else:
220                 # xxx update the record ...
221                 pass
222
223
224             site_record.stale = False
225 <<<<<<< HEAD:sfa/importer/iotlabimporter.py
226             self.import_nodes(site['node_ids'], nodes_by_id, iotlabdriver)
227
228             return
229
230     def import_nodes(self, site_node_ids, nodes_by_id, iotlabdriver):
231 =======
232             self.import_nodes(site['node_ids'], nodes_by_id, slabdriver)
233
234             return
235
236     def import_nodes(self, site_node_ids, nodes_by_id, slabdriver):
237 >>>>>>> 3fe7429... SA:sfa/importer/slabimporter.py
238         """
239
240         Creates appropriate hostnames and RegNode records for
241         each node in site_node_ids, based on the information given by the
242         dict nodes_by_id that was made from data from OAR.
243         Saves the records to the DB.
244
245         :param site_node_ids: site's node ids
246         :type site_node_ids: list of integers
247         :param nodes_by_id: dictionary , key is the node id, value is the a dict
248         with node information.
249         :type nodes_by_id: dictionary
250         :param iotlabdriver:IotlabDriver object, used to have access to iotlabdriver
251         attributes.
252 <<<<<<< HEAD:sfa/importer/iotlabimporter.py
253         :type iotlabdriver:IotlabDriver
254 =======
255         :type slabdriver:SlabDriver
256 >>>>>>> 3fe7429... SA:sfa/importer/slabimporter.py
257
258         """
259
260         for node_id in site_node_ids:
261             try:
262                 node = nodes_by_id[node_id]
263             except KeyError:
264                 self.logger.warning ("IotlabImporter: cannot find node_id %s \
265                         - ignored" %(node_id))
266                 continue
267             escaped_hrn =  \
268             self.hostname_to_hrn_escaped(iotlabdriver.iotlab_api.root_auth, \
269             node['hostname'])
270 <<<<<<< HEAD:sfa/importer/iotlabimporter.py
271             self.logger.info("IOTLABIMPORTER node %s " %(node))
272 =======
273             self.logger.info("SLABIMPORTER node %s " %(node))
274 >>>>>>> 3fe7429... SA:sfa/importer/slabimporter.py
275             hrn =  node['hrn']
276
277
278             # xxx this sounds suspicious
279             if len(hrn) > 64:
280                 hrn = hrn[:64]
281             node_record = self.find_record_by_type_hrn( 'node', hrn )
282             if not node_record:
283                 pkey = Keypair(create=True)
284                 urn = hrn_to_urn(escaped_hrn, 'node')
285                 node_gid = \
286                     self.auth_hierarchy.create_gid(urn, \
287                     create_uuid(), pkey)
288
289 <<<<<<< HEAD:sfa/importer/iotlabimporter.py
290                 def iotlab_get_authority(hrn):
291 =======
292                 def slab_get_authority(hrn):
293 >>>>>>> 3fe7429... SA:sfa/importer/slabimporter.py
294                     return hrn.split(".")[0]
295
296                 node_record = RegNode(hrn=hrn, gid=node_gid,
297                                     pointer = '-1',
298                                     authority=iotlab_get_authority(hrn))
299                 try:
300
301                     node_record.just_created()
302                     dbsession.add(node_record)
303                     dbsession.commit()
304 <<<<<<< HEAD:sfa/importer/iotlabimporter.py
305                     self.logger.info("IotlabImporter: imported node: %s" \
306                                 % node_record)
307                     self.update_just_added_records_dict(node_record)
308                 except SQLAlchemyError:
309                     self.logger.log_exc("IotlabImporter: \
310 =======
311                     self.logger.info("SlabImporter: imported node: %s" \
312                                 % node_record)
313                     self.update_just_added_records_dict(node_record)
314                 except SQLAlchemyError:
315                     self.logger.log_exc("SlabImporter: \
316 >>>>>>> 3fe7429... SA:sfa/importer/slabimporter.py
317                                     failed to import node")
318             else:
319                 #TODO:  xxx update the record ...
320                 pass
321             node_record.stale = False
322 <<<<<<< HEAD:sfa/importer/iotlabimporter.py
323
324
325     def init_person_key (self, person, iotlab_key):
326 =======
327
328
329     def init_person_key (self, person, slab_key):
330 >>>>>>> 3fe7429... SA:sfa/importer/slabimporter.py
331         """
332
333         Returns a tuple pubkey and pkey.
334
335         :param person Person's data.
336         :type person: dict
337 <<<<<<< HEAD:sfa/importer/iotlabimporter.py
338         :param iotlab_key: SSH public key, from LDAP user's data.
339 =======
340         :param slab_key: SSH public key, from LDAP user's data.
341 >>>>>>> 3fe7429... SA:sfa/importer/slabimporter.py
342         RSA type supported.
343         :type iotlab_key: string
344         :rtype (string, Keypair)
345         """
346         pubkey = None
347         if  person['pkey']:
348             # randomly pick first key in set
349 <<<<<<< HEAD:sfa/importer/iotlabimporter.py
350             pubkey = iotlab_key
351 =======
352             pubkey = slab_key
353 >>>>>>> 3fe7429... SA:sfa/importer/slabimporter.py
354
355             try:
356                 pkey = convert_public_key(pubkey)
357             except TypeError:
358                 #key not good. create another pkey
359                 self.logger.warn('IotlabImporter: \
360                                     unable to convert public \
361                                     key for %s' %person['hrn'])
362                 pkey = Keypair(create=True)
363
364         else:
365             # the user has no keys.
366             #Creating a random keypair for the user's gid
367             self.logger.warn("IotlabImporter: person %s does not have a  \
368                         public key" %(person['hrn']))
369             pkey = Keypair(create=True)
370         return (pubkey, pkey)
371
372
373 <<<<<<< HEAD:sfa/importer/iotlabimporter.py
374     def import_persons_and_slices(self, iotlabdriver):
375 =======
376     def import_persons_and_slices(self, slabdriver):
377 >>>>>>> 3fe7429... SA:sfa/importer/slabimporter.py
378         """
379
380         Gets user data from LDAP, process the information.
381         Creates hrn for the user's slice, the user's gid, creates
382         the RegUser record associated with user. Creates the RegKey record
383         associated nwith the user's key.
384         Saves those records into the SFA DB.
385         import the user's slice onto the database as well by calling
386         import_slice.
387
388 <<<<<<< HEAD:sfa/importer/iotlabimporter.py
389         :param iotlabdriver:IotlabDriver object, used to have access to iotlabdriver
390 =======
391         :param slabdriver:SlabDriver object, used to have access to slabdriver
392 >>>>>>> 3fe7429... SA:sfa/importer/slabimporter.py
393         attributes.
394         :type iotlabdriver:IotlabDriver
395         """
396 <<<<<<< HEAD:sfa/importer/iotlabimporter.py
397         ldap_person_listdict = iotlabdriver.iotlab_api.GetPersons()
398         self.logger.info("IOTLABIMPORT \t ldap_person_listdict %s \r\n" \
399 =======
400         ldap_person_listdict = slabdriver.slab_api.GetPersons()
401         self.logger.info("SLABIMPORT \t ldap_person_listdict %s \r\n" \
402 >>>>>>> 3fe7429... SA:sfa/importer/slabimporter.py
403                 %(ldap_person_listdict))
404
405          # import persons
406         for person in ldap_person_listdict :
407
408 <<<<<<< HEAD:sfa/importer/iotlabimporter.py
409             self.logger.info("IotlabImporter: person :" %(person))
410 =======
411             self.logger.info("SlabImporter: person :" %(person))
412 >>>>>>> 3fe7429... SA:sfa/importer/slabimporter.py
413             if 'ssh-rsa' not in person['pkey']:
414                 #people with invalid ssh key (ssh-dss, empty, bullshit keys...)
415                 #won't be imported
416                 continue
417             person_hrn = person['hrn']
418             slice_hrn = self.slicename_to_hrn(person['hrn'])
419
420             # xxx suspicious again
421             if len(person_hrn) > 64:
422                 person_hrn = person_hrn[:64]
423             person_urn = hrn_to_urn(person_hrn, 'user')
424
425
426 <<<<<<< HEAD:sfa/importer/iotlabimporter.py
427             self.logger.info("IotlabImporter: users_rec_by_email %s " \
428 =======
429             self.logger.info("SlabImporter: users_rec_by_email %s " \
430 >>>>>>> 3fe7429... SA:sfa/importer/slabimporter.py
431                                             %(self.users_rec_by_email))
432
433             #Check if user using person['email'] from LDAP is already registered
434             #in SFA. One email = one person. In this case, do not create another
435             #record for this person
436 <<<<<<< HEAD:sfa/importer/iotlabimporter.py
437             #person_hrn returned by GetPerson based on iotlab root auth +
438 =======
439             #person_hrn returned by GetPerson based on senslab root auth +
440 >>>>>>> 3fe7429... SA:sfa/importer/slabimporter.py
441             #uid ldap
442             user_record = self.find_record_by_type_hrn('user', person_hrn)
443
444             if not user_record and  person['email'] in self.users_rec_by_email:
445                 user_record = self.users_rec_by_email[person['email']]
446                 person_hrn = user_record.hrn
447                 person_urn = hrn_to_urn(person_hrn, 'user')
448
449
450             slice_record = self.find_record_by_type_hrn ('slice', slice_hrn)
451
452 <<<<<<< HEAD:sfa/importer/iotlabimporter.py
453             iotlab_key = person['pkey']
454 =======
455             slab_key = person['pkey']
456 >>>>>>> 3fe7429... SA:sfa/importer/slabimporter.py
457             # new person
458             if not user_record:
459                 (pubkey, pkey) = self.init_person_key(person, iotlab_key)
460                 if pubkey is not None and pkey is not None :
461                     person_gid = \
462                     self.auth_hierarchy.create_gid(person_urn, \
463                     create_uuid(), pkey)
464                     if person['email']:
465                         self.logger.debug( "SLAB IMPORTER \
466                             PERSON EMAIL OK email %s " %(person['email']))
467                         person_gid.set_email(person['email'])
468                         user_record = RegUser(hrn=person_hrn, \
469                                             gid=person_gid,
470                                             pointer='-1',
471                                             authority=get_authority(person_hrn),
472                                             email=person['email'])
473                     else:
474                         user_record = RegUser(hrn=person_hrn, \
475                                             gid=person_gid,
476                                             pointer='-1',
477                                             authority=get_authority(person_hrn))
478
479                     if pubkey:
480                         user_record.reg_keys = [RegKey(pubkey)]
481                     else:
482                         self.logger.warning("No key found for user %s" \
483                         %(user_record))
484
485                         try:
486                             user_record.just_created()
487                             dbsession.add (user_record)
488                             dbsession.commit()
489                             self.logger.info("IotlabImporter: imported person %s"\
490                             %(user_record))
491                             self.update_just_added_records_dict( user_record )
492
493                         except SQLAlchemyError:
494 <<<<<<< HEAD:sfa/importer/iotlabimporter.py
495                             self.logger.log_exc("IotlabImporter: \
496 =======
497                             self.logger.log_exc("SlabImporter: \
498 >>>>>>> 3fe7429... SA:sfa/importer/slabimporter.py
499                                 failed to import person  %s"%(person))
500             else:
501                 # update the record ?
502                 # if user's primary key has changed then we need to update
503                 # the users gid by forcing an update here
504                 sfa_keys = user_record.reg_keys
505
506                 new_key = False
507 <<<<<<< HEAD:sfa/importer/iotlabimporter.py
508                 if iotlab_key is not sfa_keys :
509 =======
510                 if slab_key is not sfa_keys :
511 >>>>>>> 3fe7429... SA:sfa/importer/slabimporter.py
512                     new_key = True
513                 if new_key:
514                     self.logger.info("IotlabImporter: \t \t USER UPDATE \
515                         person: %s" %(person['hrn']))
516                     (pubkey, pkey) = self.init_person_key (person, iotlab_key)
517                     person_gid = \
518                         self.auth_hierarchy.create_gid(person_urn, \
519                         create_uuid(), pkey)
520                     if not pubkey:
521                         user_record.reg_keys = []
522                     else:
523                         user_record.reg_keys = [RegKey(pubkey)]
524                     self.logger.info("IotlabImporter: updated person: %s" \
525                     % (user_record))
526
527                 if person['email']:
528                     user_record.email = person['email']
529
530             try:
531                 dbsession.commit()
532                 user_record.stale = False
533             except SQLAlchemyError:
534 <<<<<<< HEAD:sfa/importer/iotlabimporter.py
535                 self.logger.log_exc("IotlabImporter: \
536 =======
537                 self.logger.log_exc("SlabImporter: \
538 >>>>>>> 3fe7429... SA:sfa/importer/slabimporter.py
539                 failed to update person  %s"%(person))
540
541             self.import_slice(slice_hrn, slice_record, user_record)
542
543
544     def import_slice(self, slice_hrn, slice_record, user_record):
545         """
546
547          Create RegSlice record according to the slice hrn if the slice
548          does not exist yet.Creates a relationship with the user record
549          associated with the slice.
550          Commit the record to the database.
551
552
553         :param slice_hrn: Human readable name of the slice.
554         :type slice_hrn: string
555         :param slice_record: record of the slice found in the DB, if any.
556         :type slice_record: RegSlice or None
557         :param user_record: user record found in the DB if any.
558         :type user_record: RegUser
559
560         .. todo::Update the record if a slice record already exists.
561         """
562         if not slice_record :
563             pkey = Keypair(create=True)
564             urn = hrn_to_urn(slice_hrn, 'slice')
565             slice_gid = \
566                 self.auth_hierarchy.create_gid(urn, \
567                 create_uuid(), pkey)
568             slice_record = RegSlice (hrn=slice_hrn, gid=slice_gid,
569                                         pointer='-1',
570                                         authority=get_authority(slice_hrn))
571             try:
572                 slice_record.just_created()
573                 dbsession.add(slice_record)
574                 dbsession.commit()
575
576
577                 self.update_just_added_records_dict ( slice_record )
578
579             except SQLAlchemyError:
580 <<<<<<< HEAD:sfa/importer/iotlabimporter.py
581                 self.logger.log_exc("IotlabImporter: failed to import slice")
582
583         #No slice update upon import in iotlab
584 =======
585                 self.logger.log_exc("SlabImporter: failed to import slice")
586
587         #No slice update upon import in senslab
588 >>>>>>> 3fe7429... SA:sfa/importer/slabimporter.py
589         else:
590             # xxx update the record ...
591             self.logger.warning ("Slice update not yet implemented")
592             pass
593         # record current users affiliated with the slice
594
595
596         slice_record.reg_researchers =  [user_record]
597         try:
598             dbsession.commit()
599             slice_record.stale = False
600         except SQLAlchemyError:
601 <<<<<<< HEAD:sfa/importer/iotlabimporter.py
602             self.logger.log_exc("IotlabImporter: failed to update slice")
603 =======
604             self.logger.log_exc("SlabImporter: failed to update slice")
605 >>>>>>> 3fe7429... SA:sfa/importer/slabimporter.py
606
607
608     def run (self, options):
609         """
610         Create the special iotlab table, iotlab_xp, in the iotlab database.
611         Import everything (users, slices, nodes and sites from OAR
612         and LDAP) into the SFA database.
613         Delete stale records that are no longer in OAR or LDAP.
614         :param options:
615         :type options:
616         """
617         config = Config()
618
619 <<<<<<< HEAD:sfa/importer/iotlabimporter.py
620         iotlabdriver = IotlabDriver(config)
621
622         #Create special slice table for iotlab
623
624         if not iotlabdriver.db.exists('iotlab_xp'):
625             iotlabdriver.db.createtable()
626             self.logger.info ("IotlabImporter.run:  iotlab_xp table created ")
627
628
629         # import site and node records in site into the SFA db.
630         self.import_sites_and_nodes(iotlabdriver)
631         #import users and slice into the SFA DB.
632         self.import_persons_and_slices(iotlabdriver)
633
634          ### remove stale records
635         # special records must be preserved
636         system_hrns = [iotlabdriver.hrn, iotlabdriver.iotlab_api.root_auth,  \
637                                         iotlabdriver.hrn+ '.slicemanager']
638 =======
639         slabdriver = SlabDriver(config)
640
641         #Create special slice table for senslab
642
643         if not slabdriver.db.exists('slab_xp'):
644             slabdriver.db.createtable()
645             self.logger.info ("SlabImporter.run:  slab_xp table created ")
646
647
648         # import site and node records in site into the SFA db.
649         self.import_sites_and_nodes(slabdriver)
650         #import users and slice into the SFA DB.
651         self.import_persons_and_slices(slabdriver)
652
653          ### remove stale records
654         # special records must be preserved
655         system_hrns = [slabdriver.hrn, slabdriver.slab_api.root_auth,  \
656                                         slabdriver.hrn+ '.slicemanager']
657 >>>>>>> 3fe7429... SA:sfa/importer/slabimporter.py
658         for record in self.all_records:
659             if record.hrn in system_hrns:
660                 record.stale = False
661             if record.peer_authority:
662                 record.stale = False
663
664
665         for record in self.all_records:
666             if record.type == 'user':
667                 self.logger.info("IotlabImporter: stale records: hrn %s %s" \
668                                             %(record.hrn,record.stale) )
669             try:
670                 stale = record.stale
671             except :
672                 stale = True
673                 self.logger.warning("stale not found with %s"%record)
674             if stale:
675                 self.logger.info("IotlabImporter: deleting stale record: %s" \
676                 %(record))
677
678                 try:
679                     dbsession.delete(record)
680                     dbsession.commit()
681                 except SQLAlchemyError:
682                     self.logger.log_exc("IotlabImporter: failed to delete stale \
683                     record %s" %(record) )
684
685