diff --git a/jc/lib.py b/jc/lib.py index a6c06064..a587e281 100644 --- a/jc/lib.py +++ b/jc/lib.py @@ -161,6 +161,7 @@ parsers = [ 'top-s', 'tracepath', 'traceroute', + 'udevadm', 'ufw', 'ufw-appinfo', 'uname', diff --git a/jc/parsers/udevadm.py b/jc/parsers/udevadm.py new file mode 100644 index 00000000..4dce1dc7 --- /dev/null +++ b/jc/parsers/udevadm.py @@ -0,0 +1,118 @@ +"""jc - JSON Convert `udevadm info` command output parser + +Usage (cli): + + $ udevadm info --query=all /dev/sda | jc --udevadm + +or + + $ jc udevadm info --query=all /dev/sda + +Usage (module): + + import jc + result = jc.parse('udevadm', udevadm_command_output) + +Schema: + + [ + { + "udevadm": string, + "bar": boolean, + "baz": integer + } + ] + +Examples: + + $ udevadm info --query=all /dev/sda | jc --udevadm -p + [] + + $ udevadm info --query=all /dev/sda | jc --udevadm -p -r + [] +""" +from typing import List, Dict +import jc.utils + + +class info(): + """Provides parser metadata (version, author, etc.)""" + version = '1.0' + description = '`udevadm info` command parser' + author = 'Kelly Brazil' + author_email = 'kellyjonbrazil@gmail.com' + compatible = ['linux'] + magic_commands = ['udevadm info'] + + +__version__ = info.version + + +def _process(proc_data: Dict) -> Dict: + """ + Final processing to conform to the schema. + + Parameters: + + proc_data: (List of Dictionaries) raw structured data to process + + Returns: + + List of Dictionaries. Structured to conform to the schema. + """ + return proc_data + + +def parse( + data: str, + raw: bool = False, + quiet: bool = False +) -> Dict: + """ + Main text parsing function + + Parameters: + + data: (string) text data to parse + raw: (boolean) unprocessed output if True + quiet: (boolean) suppress warning messages if True + + Returns: + + Dictionary. Raw or processed structured data. + """ + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) + + raw_output: Dict = {} + s_list: List = [] + e_list: List = [] + + if jc.utils.has_data(data): + for line in filter(None, data.splitlines()): + prefix, value = line.split(maxsplit=1) + + if prefix == 'P:': + raw_output['P'] = value + continue + + if prefix == 'S:': + s_list.append(value) + continue + + if prefix == 'E:': + e_list.append(value) + continue + + raw_output[prefix[:-1]] = value + + if s_list: + raw_output['S'] = s_list + + if e_list: + raw_output['E'] = {} + for item in e_list: + k, v = item.split('=') + raw_output['E'][k] = v + + return raw_output if raw else _process(raw_output) diff --git a/tests/fixtures/generic/udevadm.out b/tests/fixtures/generic/udevadm.out new file mode 100644 index 00000000..965601eb --- /dev/null +++ b/tests/fixtures/generic/udevadm.out @@ -0,0 +1,33 @@ +P: /devices/pci0000:00/0000:00:10.0/host32/target32:0:0/32:0:0:0/block/sda +N: sda +L: 0 +S: disk/by-path/pci-0000:00:10.0-scsi-0:0:0:0 +E: DEVPATH=/devices/pci0000:00/0000:00:10.0/host32/target32:0:0/32:0:0:0/block/sda +E: DEVNAME=/dev/sda +E: DEVTYPE=disk +E: MAJOR=8 +E: MINOR=0 +E: SUBSYSTEM=block +E: USEC_INITIALIZED=6100111 +E: SCSI_TPGS=0 +E: SCSI_TYPE=disk +E: SCSI_VENDOR=VMware, +E: SCSI_VENDOR_ENC=VMware,\x20 +E: SCSI_MODEL=VMware_Virtual_S +E: SCSI_MODEL_ENC=VMware\x20Virtual\x20S +E: SCSI_REVISION=1.0 +E: ID_SCSI=1 +E: ID_VENDOR=VMware_ +E: ID_VENDOR_ENC=VMware\x2c\x20 +E: ID_MODEL=VMware_Virtual_S +E: ID_MODEL_ENC=VMware\x20Virtual\x20S +E: ID_REVISION=1.0 +E: ID_TYPE=disk +E: MPATH_SBIN_PATH=/sbin +E: ID_BUS=scsi +E: ID_PATH=pci-0000:00:10.0-scsi-0:0:0:0 +E: ID_PATH_TAG=pci-0000_00_10_0-scsi-0_0_0_0 +E: ID_PART_TABLE_UUID=a5bd0c01-4210-46f2-b558-5c11c209a8f7 +E: ID_PART_TABLE_TYPE=gpt +E: DEVLINKS=/dev/disk/by-path/pci-0000:00:10.0-scsi-0:0:0:0 +E: TAGS=:systemd: