]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/telemetry: fix device id splitting when anonymizing serial 36855/head
authorYaarit Hatuka <yaarit@redhat.com>
Thu, 27 Aug 2020 03:04:34 +0000 (23:04 -0400)
committerYaarit Hatuka <yaarit@redhat.com>
Thu, 27 Aug 2020 03:16:25 +0000 (23:16 -0400)
Anonymizing the serial number in the device id string fails in rare
cases where 'vendor' and 'model' are missing from the device id
string. Ideally, device id is generated (in blkdev.cc) as
'vendor_model_serial', in case all fields were successfully retrieved
from the device. In cases where they were not, device id can also be
generated as 'model_serial' or 'serial'. Splitting by '_' fails in the
latter case (since 'serial' is the only element in the string).

In order to anonymize serial numbers in smartctl reports we now rely
on the serial number value as retrieved from the raw smartctl report
itself (as opposed to the one in device id). That's in order to avoid
possible inconsistencies between the serial retrieved from device id and
the one in the report.

Fixes: https://tracker.ceph.com/issues/46977
Signed-off-by: Yaarit Hatuka <yaarit@redhat.com>
src/pybind/mgr/telemetry/module.py

index fef56e4bd45d57d6074f3f9b1ac55ee440096c0c..bc68e12896759929ec381a23325d2047ea36c159 100644 (file)
@@ -398,21 +398,29 @@ class Module(MgrModule):
             if not anon_host:
                 anon_host = str(uuid.uuid1())
                 self.set_store('host-id/%s' % host, anon_host)
+            serial = None
             for dev, rep in m.items():
                 rep['host_id'] = anon_host
+                if serial is None and 'serial_number' in rep:
+                    serial = rep['serial_number']
 
             # anonymize device id
             anon_devid = self.get_store('devid-id/%s' % devid)
             if not anon_devid:
-                anon_devid = f"{devid.rsplit('_', 1)[0]}_{uuid.uuid1()}"
+                # ideally devid is 'vendor_model_serial',
+                # but can also be 'model_serial', 'serial'
+                if '_' in devid:
+                    anon_devid = f"{devid.rsplit('_', 1)[0]}_{uuid.uuid1()}"
+                else:
+                    anon_devid = str(uuid.uuid1())
                 self.set_store('devid-id/%s' % devid, anon_devid)
             self.log.info('devid %s / %s, host %s / %s' % (devid, anon_devid,
                                                            host, anon_host))
 
             # anonymize the smartctl report itself
-            serial = devid.rsplit('_', 1)[1]
-            m_str = json.dumps(m)
-            m = json.loads(m_str.replace(serial, 'deleted'))
+            if serial:
+                m_str = json.dumps(m)
+                m = json.loads(m_str.replace(serial, 'deleted'))
 
             if anon_host not in res:
                 res[anon_host] = {}