From 383c2e356068bde2ff72a923bc4c6f7740a1eb1d Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 4 Jul 2023 16:45:04 +0200 Subject: [PATCH] snapshotparser --- ereuse_devicehub/config.py | 2 +- ereuse_devicehub/inventory/forms.py | 21 ++++---- ereuse_devicehub/parser/parser.py | 77 +++++++++++++++++++++++++---- ereuse_devicehub/parser/schemas.py | 4 +- 4 files changed, 81 insertions(+), 23 deletions(-) diff --git a/ereuse_devicehub/config.py b/ereuse_devicehub/config.py index 1b89006a..185f1fa5 100644 --- a/ereuse_devicehub/config.py +++ b/ereuse_devicehub/config.py @@ -63,7 +63,7 @@ class DevicehubConfig(Config): """The minimum version of ereuse.org workbench that this devicehub accepts. we recommend not changing this value. """ - SCHEMA_WORKBENCH = ["1.0.0"] + SCHEMA_HWMD = ["1.0.0"] TMP_SNAPSHOTS = config('TMP_SNAPSHOTS', '/tmp/snapshots') TMP_LIVES = config('TMP_LIVES', '/tmp/lives') diff --git a/ereuse_devicehub/inventory/forms.py b/ereuse_devicehub/inventory/forms.py index f9b10aa2..cd6488db 100644 --- a/ereuse_devicehub/inventory/forms.py +++ b/ereuse_devicehub/inventory/forms.py @@ -39,7 +39,7 @@ from ereuse_devicehub.inventory.models import ( TransferCustomerDetails, ) from ereuse_devicehub.parser.models import PlaceholdersLog, SnapshotsLog -from ereuse_devicehub.parser.parser import ParseSnapshotLsHw +from ereuse_devicehub.parser.parser import ParseSnapshot, ParseSnapshotLsHw from ereuse_devicehub.parser.schemas import Snapshot_lite from ereuse_devicehub.resources.action.models import Snapshot, Trade from ereuse_devicehub.resources.action.schemas import Snapshot as SnapshotSchema @@ -315,18 +315,12 @@ class UploadSnapshotForm(SnapshotMixin, FlaskForm): return True - def is_wb_lite_snapshot(self, version: str) -> bool: - is_lite = False - if version in app.config['SCHEMA_WORKBENCH']: - is_lite = True - - return is_lite - def save(self, commit=True, user_trusts=True): if any([x == 'Error' for x in self.result.values()]): return schema = SnapshotSchema() schema_lite = Snapshot_lite() + schemas_hwmd = {'1.0.0': Snapshot_lite()} devices = [] self.tmp_snapshots = app.config['TMP_SNAPSHOTS'] for filename, snapshot_json in self.snapshots: @@ -336,9 +330,16 @@ class UploadSnapshotForm(SnapshotMixin, FlaskForm): self.uuid = snapshot_json.get('uuid') self.sid = snapshot_json.get('sid') - if self.is_wb_lite_snapshot(self.version): + if snapshot_json.get('hwmd'): + schema_api = snapshot_json.get('schema_api') + schema_lite = schemas_hwmd.get(schema_api) + if not schema_lite: + txt = "Error: No there are schema_api in the snapshot {}" + txt = txt.format(self.uuid) + raise txt + self.snapshot_json = schema_lite.load(snapshot_json) - snapshot_json = ParseSnapshotLsHw(self.snapshot_json).snapshot_json + snapshot_json = ParseSnapshot(self.snapshot_json).snapshot_json else: self.version = snapshot_json.get('version') system_uuid = self.get_uuid(debug) diff --git a/ereuse_devicehub/parser/parser.py b/ereuse_devicehub/parser/parser.py index 39f4bee8..eef41bdb 100644 --- a/ereuse_devicehub/parser/parser.py +++ b/ereuse_devicehub/parser/parser.py @@ -31,7 +31,7 @@ class ParseSnapshot: self.lshw = self.loads(self.lshw_raw) self.hwinfo = self.parse_hwinfo() - self.set_basic_datas() + self.set_computer() self.set_components() self.snapshot_json = { "device": self.device, @@ -48,8 +48,10 @@ class ParseSnapshot: def get_snapshot(self): return Snapshot().load(self.snapshot_json) - def set_basic_datas(self): - # import pdb; pdb.set_trace() + def set_computer(self): + import pdb + + pdb.set_trace() self.device['manufacturer'] = self.dmi.manufacturer() self.device['model'] = self.dmi.model() self.device['serialNumber'] = self.dmi.serial_number() @@ -57,6 +59,8 @@ class ParseSnapshot: self.device['sku'] = self.get_sku() self.device['version'] = self.get_version() self.device['system_uuid'] = self.get_uuid() + self.device['family'] = self.get_family() + self.device['chassis'] = self.get_chassis_dh() def set_components(self): self.get_cpu() @@ -66,8 +70,10 @@ class ParseSnapshot: self.get_networks() def get_cpu(self): - # TODO @cayop generation, brand and address not exist in dmidecode for cpu in self.dmi.get('Processor'): + serial = cpu.get('Serial Number') + if serial == 'Not Specified' or not serial: + serial = cpu.get('ID') self.components.append( { "actions": [], @@ -77,13 +83,21 @@ class ParseSnapshot: "model": cpu.get('Version'), "threads": int(cpu.get('Thread Count', 1)), "manufacturer": cpu.get('Manufacturer'), - "serialNumber": cpu.get('Serial Number'), - "generation": cpu.get('Generation'), - "brand": cpu.get('Brand'), - "address": cpu.get('Address'), + "serialNumber": serial, + "generation": None, + "brand": cpu.get('Family'), + "address": self.get_cpu_address(cpu), } ) + def get_cpu_address(self, cpu): + default = 64 + for ch in self.lshw.get('children', []): + for c in ch.get('children', []): + if c['class'] == 'processor': + return c.get('width', default) + return default + def get_ram(self): # TODO @cayop format and model not exist in dmidecode for ram in self.dmi.get("Memory Device"): @@ -199,10 +213,13 @@ class ParseSnapshot: return self.dmi.get("System")[0].get("Version", self.default) def get_uuid(self): - return self.dmi.get("System")[0].get("UUID", self.default) + return self.dmi.get("System")[0].get("UUID", '') + + def get_family(self): + return self.dmi.get("System")[0].get("Family", '') def get_chassis(self): - return self.dmi.get("Chassis")[0].get("Type", self.default) + return self.dmi.get("Chassis")[0].get("Type", '_virtual') def get_type(self): chassis_type = self.get_chassis() @@ -242,6 +259,31 @@ class ParseSnapshot: return k return self.default + def get_chassis_dh(self): + CHASSIS_DH = { + 'Tower': {'desktop', 'low-profile', 'tower', 'server'}, + 'Docking': {'docking'}, + 'AllInOne': {'all-in-one'}, + 'Microtower': {'mini-tower', 'space-saving', 'mini'}, + 'PizzaBox': {'pizzabox'}, + 'Lunchbox': {'lunchbox'}, + 'Stick': {'stick'}, + 'Netbook': {'notebook', 'sub-notebook'}, + 'Handheld': {'handheld'}, + 'Laptop': {'portable', 'laptop'}, + 'Convertible': {'convertible'}, + 'Detachable': {'detachable'}, + 'Tablet': {'tablet'}, + 'Virtual': {'_virtual'}, + } + + chassis = self.get_chassis() + lower_type = chassis.lower() + for k, v in CHASSIS_DH.items(): + if lower_type in v: + return k + return self.default + def get_data_storage(self): for sm in self.smart: @@ -318,6 +360,21 @@ class ParseSnapshot: return json.loads(x) return x + def errors(self, txt=None, severity=Severity.Error): + if not txt: + return self._errors + + logger.error(txt) + self._errors.append(txt) + error = SnapshotsLog( + description=txt, + snapshot_uuid=self.uuid, + severity=severity, + sid=self.sid, + version=self.version, + ) + error.save() + class ParseSnapshotLsHw: def __init__(self, snapshot, default="n/a"): diff --git a/ereuse_devicehub/parser/schemas.py b/ereuse_devicehub/parser/schemas.py index 415d3147..8b0fdd34 100644 --- a/ereuse_devicehub/parser/schemas.py +++ b/ereuse_devicehub/parser/schemas.py @@ -45,11 +45,11 @@ class Snapshot_lite(Thing): @validates_schema def validate_workbench_version(self, data: dict): - if data['schema_api'] not in app.config['SCHEMA_WORKBENCH']: + if data['schema_api'] not in app.config['SCHEMA_HWMD']: raise ValidationError( 'Min. supported Workbench version is ' '{} but yours is {}.'.format( - app.config['SCHEMA_WORKBENCH'][0], data['version'] + app.config['SCHEMA_HWMD'][0], data['version'] ), field_names=['version'], )