From db47f35783e46a8299533c22146d851509f6ceb2 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Wed, 30 Jun 2021 12:38:36 -0700 Subject: [PATCH] add working sfdisk parser --- CHANGELOG | 3 + README.md | 1 + docs/parsers/sfdisk.md | 213 +++++++++++++++ jc/__init__.py | 2 +- jc/cli.py | 1 + jc/man/jc.1.gz | Bin 2691 -> 2700 bytes jc/parsers/sfdisk.py | 325 +++++++++++++++++++++++ jc/utils.py | 2 +- man/jc.1.gz | Bin 2691 -> 2700 bytes setup.py | 2 +- tests/fixtures/centos-7.7/sfdisk-d.out | 8 + tests/fixtures/centos-7.7/sfdisk-l.out | 14 + tests/fixtures/centos-7.7/sfdisk-luB.out | 14 + tests/fixtures/centos-7.7/sfdisk-luM.out | 14 + tests/fixtures/centos-7.7/sfdisk-luS.out | 14 + 15 files changed, 610 insertions(+), 3 deletions(-) create mode 100644 docs/parsers/sfdisk.md create mode 100644 jc/parsers/sfdisk.py create mode 100644 tests/fixtures/centos-7.7/sfdisk-d.out create mode 100644 tests/fixtures/centos-7.7/sfdisk-l.out create mode 100644 tests/fixtures/centos-7.7/sfdisk-luB.out create mode 100644 tests/fixtures/centos-7.7/sfdisk-luM.out create mode 100644 tests/fixtures/centos-7.7/sfdisk-luS.out diff --git a/CHANGELOG b/CHANGELOG index 766c9008..fdc1dc31 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,8 @@ jc changelog +20210630 v1.15.7 +- Add sfdisk command parser tested on linux + 20210628 v1.15.6 - Fix issue to only load local plugin parsers that have filenames that end in .py diff --git a/README.md b/README.md index 31bb0c95..f1faa28a 100644 --- a/README.md +++ b/README.md @@ -169,6 +169,7 @@ The JSON output can be compact (default) or pretty formatted with the `-p` optio - `--ps` enables the `ps` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/ps)) - `--route` enables the `route` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/route)) - `--rpm-qi` enables the `rpm -qi` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/rpm_qi)) +- `--sfdisk` enables the `sfdisk` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/sfdisk)) - `--shadow` enables the `/etc/shadow` file parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/shadow)) - `--ss` enables the `ss` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/ss)) - `--stat` enables the `stat` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/stat)) diff --git a/docs/parsers/sfdisk.md b/docs/parsers/sfdisk.md new file mode 100644 index 00000000..6eb8bb6f --- /dev/null +++ b/docs/parsers/sfdisk.md @@ -0,0 +1,213 @@ +[Home](https://kellyjonbrazil.github.io/jc/) + +# jc.parsers.sfdisk +jc - JSON CLI output utility `sfdisk` command output parser + +Supports the following `sfdisk` options: +- `-l` +- `-d` +- `-uM` +- `-uC` +- `-uS` +- `-uB` + +Usage (cli): + + # sfdisk -l | jc --sfdisk + + or + + # jc sfdisk -l + +Usage (module): + + import jc.parsers.sfdisk + result = jc.parsers.sfdisk.parse(sfdisk_command_output) + +Schema: + + [ + { + "disk": string, + "cylinders": integer, + "heads": integer, + "sectors_per_track": integer, + "units": string, + "partitions": [ + { + "device": string, + "boot": boolean, + "start": integer, + "end": integer, + "size": integer, + "cyls": integer, + "mib": integer, + "blocks": integer, + "sectors": integer, + "id": string, + "system": string + } + ] + } + ] + +Examples: + + $ sfdisk -l | jc --sfdisk -p + [ + { + "disk": "/dev/sda", + "cylinders": 2610, + "heads": 255, + "sectors_per_track": 63, + "units": "cylinders of 8225280 bytes, blocks of 1024 bytes, counting from 0", + "partitions": [ + { + "device": "/dev/sda1", + "boot": true, + "start": 0, + "end": null, + "cyls": null, + "blocks": 1048576, + "id": "83", + "system": "Linux" + }, + { + "device": "/dev/sda2", + "boot": false, + "start": 130, + "end": null, + "cyls": null, + "blocks": 19921920, + "id": "8e", + "system": "Linux LVM" + }, + { + "device": "/dev/sda3", + "boot": false, + "start": 0, + "end": null, + "cyls": 0, + "blocks": 0, + "id": "0", + "system": "Empty" + }, + { + "device": "/dev/sda4", + "boot": false, + "start": 0, + "end": null, + "cyls": 0, + "blocks": 0, + "id": "0", + "system": "Empty" + } + ] + }, + { + "disk": "/dev/mapper/centos-root", + "cylinders": 2218, + "heads": 255, + "sectors_per_track": 63 + }, + { + "disk": "/dev/mapper/centos-swap", + "cylinders": 261, + "heads": 255, + "sectors_per_track": 63 + } + ] + + $ sfdisk | jc --sfdisk -p -r + [ + { + "disk": "/dev/sda", + "cylinders": "2610", + "heads": "255", + "sectors_per_track": "63", + "units": "cylinders of 8225280 bytes, blocks of 1024 bytes, counting from 0", + "partitions": [ + { + "device": "/dev/sda1", + "boot": "*", + "start": "0+", + "end": "130-", + "cyls": "131-", + "blocks": "1048576", + "id": "83", + "system": "Linux" + }, + { + "device": "/dev/sda2", + "boot": null, + "start": "130+", + "end": "2610-", + "cyls": "2481-", + "blocks": "19921920", + "id": "8e", + "system": "Linux LVM" + }, + { + "device": "/dev/sda3", + "boot": null, + "start": "0", + "end": "-", + "cyls": "0", + "blocks": "0", + "id": "0", + "system": "Empty" + }, + { + "device": "/dev/sda4", + "boot": null, + "start": "0", + "end": "-", + "cyls": "0", + "blocks": "0", + "id": "0", + "system": "Empty" + } + ] + }, + { + "disk": "/dev/mapper/centos-root", + "cylinders": "2218", + "heads": "255", + "sectors_per_track": "63" + }, + { + "disk": "/dev/mapper/centos-swap", + "cylinders": "261", + "heads": "255", + "sectors_per_track": "63" + } + ] + + +## info +```python +info() +``` +Provides parser metadata (version, author, etc.) + +## parse +```python +parse(data, raw=False, quiet=False) +``` + +Main text parsing function + +Parameters: + + data: (string) text data to parse + raw: (boolean) output preprocessed JSON if True + quiet: (boolean) suppress warning messages if True + +Returns: + + List of Dictionaries. Raw or processed structured data. + +## Parser Information +Compatibility: linux + +Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/jc/__init__.py b/jc/__init__.py index c1c3d337..a79d1d71 100644 --- a/jc/__init__.py +++ b/jc/__init__.py @@ -86,4 +86,4 @@ Module Example: """ name = 'jc' -__version__ = '1.15.6' +__version__ = '1.15.7' diff --git a/jc/cli.py b/jc/cli.py index e0a3db8c..4dafde69 100644 --- a/jc/cli.py +++ b/jc/cli.py @@ -94,6 +94,7 @@ parsers = [ 'ps', 'route', 'rpm-qi', + 'sfdisk', 'shadow', 'ss', 'stat', diff --git a/jc/man/jc.1.gz b/jc/man/jc.1.gz index 4e75e0f4cd2473a07be21a705ddc56aa89927fe6..b160d5bb7b7cae79be48ad3fc4639006305f5154 100644 GIT binary patch literal 2700 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 literal 2691 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 diff --git a/jc/parsers/sfdisk.py b/jc/parsers/sfdisk.py new file mode 100644 index 00000000..1debe6dd --- /dev/null +++ b/jc/parsers/sfdisk.py @@ -0,0 +1,325 @@ +"""jc - JSON CLI output utility `sfdisk` command output parser + +Supports the following `sfdisk` options: +- `-l` +- `-d` +- `-uM` +- `-uC` +- `-uS` +- `-uB` + +Usage (cli): + + # sfdisk -l | jc --sfdisk + + or + + # jc sfdisk -l + +Usage (module): + + import jc.parsers.sfdisk + result = jc.parsers.sfdisk.parse(sfdisk_command_output) + +Schema: + + [ + { + "disk": string, + "cylinders": integer, + "heads": integer, + "sectors_per_track": integer, + "units": string, + "partitions": [ + { + "device": string, + "boot": boolean, + "start": integer, + "end": integer, + "size": integer, + "cyls": integer, + "mib": integer, + "blocks": integer, + "sectors": integer, + "id": string, + "system": string + } + ] + } + ] + +Examples: + + $ sfdisk -l | jc --sfdisk -p + [ + { + "disk": "/dev/sda", + "cylinders": 2610, + "heads": 255, + "sectors_per_track": 63, + "units": "cylinders of 8225280 bytes, blocks of 1024 bytes, counting from 0", + "partitions": [ + { + "device": "/dev/sda1", + "boot": true, + "start": 0, + "end": null, + "cyls": null, + "blocks": 1048576, + "id": "83", + "system": "Linux" + }, + { + "device": "/dev/sda2", + "boot": false, + "start": 130, + "end": null, + "cyls": null, + "blocks": 19921920, + "id": "8e", + "system": "Linux LVM" + }, + { + "device": "/dev/sda3", + "boot": false, + "start": 0, + "end": null, + "cyls": 0, + "blocks": 0, + "id": "0", + "system": "Empty" + }, + { + "device": "/dev/sda4", + "boot": false, + "start": 0, + "end": null, + "cyls": 0, + "blocks": 0, + "id": "0", + "system": "Empty" + } + ] + }, + { + "disk": "/dev/mapper/centos-root", + "cylinders": 2218, + "heads": 255, + "sectors_per_track": 63 + }, + { + "disk": "/dev/mapper/centos-swap", + "cylinders": 261, + "heads": 255, + "sectors_per_track": 63 + } + ] + + $ sfdisk | jc --sfdisk -p -r + [ + { + "disk": "/dev/sda", + "cylinders": "2610", + "heads": "255", + "sectors_per_track": "63", + "units": "cylinders of 8225280 bytes, blocks of 1024 bytes, counting from 0", + "partitions": [ + { + "device": "/dev/sda1", + "boot": "*", + "start": "0+", + "end": "130-", + "cyls": "131-", + "blocks": "1048576", + "id": "83", + "system": "Linux" + }, + { + "device": "/dev/sda2", + "boot": null, + "start": "130+", + "end": "2610-", + "cyls": "2481-", + "blocks": "19921920", + "id": "8e", + "system": "Linux LVM" + }, + { + "device": "/dev/sda3", + "boot": null, + "start": "0", + "end": "-", + "cyls": "0", + "blocks": "0", + "id": "0", + "system": "Empty" + }, + { + "device": "/dev/sda4", + "boot": null, + "start": "0", + "end": "-", + "cyls": "0", + "blocks": "0", + "id": "0", + "system": "Empty" + } + ] + }, + { + "disk": "/dev/mapper/centos-root", + "cylinders": "2218", + "heads": "255", + "sectors_per_track": "63" + }, + { + "disk": "/dev/mapper/centos-swap", + "cylinders": "261", + "heads": "255", + "sectors_per_track": "63" + } + ] +""" +import jc.utils +import jc.parsers.universal + + +class info(): + """Provides parser metadata (version, author, etc.)""" + version = '1.0' + description = '`sfdisk` command parser' + author = 'Kelly Brazil' + author_email = 'kellyjonbrazil@gmail.com' + compatible = ['linux'] + magic_commands = ['sfdisk'] + + +__version__ = info.version + + +def _process(proc_data): + """ + 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. + """ + int_list = ['cylinders', 'heads', 'sectors_per_track', 'start', 'end', 'size', 'cyls', 'mib', + 'blocks', 'sectors'] + bool_list = ['boot'] + + for entry in proc_data: + for key in entry: + if key in int_list: + entry[key] = jc.utils.convert_to_int(entry[key]) + + if 'partitions' in entry: + for tp in entry['partitions']: + for key in tp: + if key in int_list: + tp[key] = jc.utils.convert_to_int(tp[key]) + if key in bool_list: + tp[key] = jc.utils.convert_to_bool(tp[key]) + + return proc_data + + +def parse(data, raw=False, quiet=False): + """ + Main text parsing function + + Parameters: + + data: (string) text data to parse + raw: (boolean) output preprocessed JSON if True + quiet: (boolean) suppress warning messages if True + + Returns: + + List of Dictionaries. Raw or processed structured data. + """ + if not quiet: + jc.utils.compatibility(__name__, info.compatible) + + raw_output = [] + item = {} + partitions = [] + option = '' + section = '' + + if jc.utils.has_data(data): + + for line in data.splitlines(): + if line.startswith('# partition table of'): + if item: + raw_output.append(item) + + item = {} + partitions = [] + option = 'd' + item['disk'] = line.split()[4] + continue + + if option == 'd': + if line.startswith('unit: '): + item['units'] = line.split()[1] + section = 'partitions' + continue + + if section == 'partitions' and line: + part = {} + part['device'] = line.split()[0] + line = line.replace(',', ' ').replace('=', ' ') + part['start'] = line.split()[3] + part['size'] = line.split()[5] + part['id'] = line.split()[7] + part['boot'] = '*' if 'bootable' in line else None + partitions.append(part) + item['partitions'] = partitions + continue + + else: + if line.startswith('Disk '): + if item: + raw_output.append(item) + + item = {} + partitions = [] + line = line.replace(':', '').replace(',', '') + item['disk'] = line.split()[1] + item['cylinders'] = line.split()[2] + item['heads'] = line.split()[4] + item['sectors_per_track'] = line.split()[6] + continue + + if line.startswith('Units: '): + item['units'] = line.split(':')[1].strip() + continue + + if 'Device' in line and 'Boot' in line and 'Start' in line and 'End' in line: + section = 'partitions' + partitions.append(line.lower().replace('#', ' ')) + continue + + if section == 'partitions' and line: + partitions.append(line) + continue + + if section == 'partitions' and line == '': + item['partitions'] = jc.parsers.universal.sparse_table_parse(partitions) + section = '' + partitions = [] + continue + + if item: + raw_output.append(item) + + if raw: + return raw_output + else: + return _process(raw_output) diff --git a/jc/utils.py b/jc/utils.py index 7974ef28..3adfd69f 100644 --- a/jc/utils.py +++ b/jc/utils.py @@ -154,7 +154,7 @@ def convert_to_bool(value): # if float converts, then bool the result # if float does not convert then look for truthy string and bool True # else False - truthy = ['y', 'yes', 'true'] + truthy = ['y', 'yes', 'true', '*'] if isinstance(value, (int, float)): return bool(value) diff --git a/man/jc.1.gz b/man/jc.1.gz index 4e75e0f4cd2473a07be21a705ddc56aa89927fe6..b160d5bb7b7cae79be48ad3fc4639006305f5154 100644 GIT binary patch literal 2700 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 literal 2691 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 diff --git a/setup.py b/setup.py index 16a536e3..e95facef 100755 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ with open('README.md', 'r') as f: setuptools.setup( name='jc', - version='1.15.6', + version='1.15.7', author='Kelly Brazil', author_email='kellyjonbrazil@gmail.com', description='Converts the output of popular command-line tools and file-types to JSON.', diff --git a/tests/fixtures/centos-7.7/sfdisk-d.out b/tests/fixtures/centos-7.7/sfdisk-d.out new file mode 100644 index 00000000..c07c0a04 --- /dev/null +++ b/tests/fixtures/centos-7.7/sfdisk-d.out @@ -0,0 +1,8 @@ +# partition table of /dev/sda +unit: sectors + +/dev/sda1 : start= 2048, size= 2097152, Id=83, bootable +/dev/sda2 : start= 2099200, size= 39843840, Id=8e +/dev/sda3 : start= 0, size= 0, Id= 0 +/dev/sda4 : start= 0, size= 0, Id= 0 + diff --git a/tests/fixtures/centos-7.7/sfdisk-l.out b/tests/fixtures/centos-7.7/sfdisk-l.out new file mode 100644 index 00000000..b067b063 --- /dev/null +++ b/tests/fixtures/centos-7.7/sfdisk-l.out @@ -0,0 +1,14 @@ + +Disk /dev/sda: 2610 cylinders, 255 heads, 63 sectors/track +Units: cylinders of 8225280 bytes, blocks of 1024 bytes, counting from 0 + + Device Boot Start End #cyls #blocks Id System +/dev/sda1 * 0+ 130- 131- 1048576 83 Linux +/dev/sda2 130+ 2610- 2481- 19921920 8e Linux LVM +/dev/sda3 0 - 0 0 0 Empty +/dev/sda4 0 - 0 0 0 Empty + +Disk /dev/mapper/centos-root: 2218 cylinders, 255 heads, 63 sectors/track + +Disk /dev/mapper/centos-swap: 261 cylinders, 255 heads, 63 sectors/track + diff --git a/tests/fixtures/centos-7.7/sfdisk-luB.out b/tests/fixtures/centos-7.7/sfdisk-luB.out new file mode 100644 index 00000000..dc1141d2 --- /dev/null +++ b/tests/fixtures/centos-7.7/sfdisk-luB.out @@ -0,0 +1,14 @@ + +Disk /dev/sda: 2610 cylinders, 255 heads, 63 sectors/track +Units: blocks of 1024 bytes, counting from 0 + + Device Boot Start End #blocks Id System +/dev/sda1 * 1024 1049599 1048576 83 Linux +/dev/sda2 1049600 20971519 19921920 8e Linux LVM +/dev/sda3 0 - 0 0 Empty +/dev/sda4 0 - 0 0 Empty + +Disk /dev/mapper/centos-root: 2218 cylinders, 255 heads, 63 sectors/track + +Disk /dev/mapper/centos-swap: 261 cylinders, 255 heads, 63 sectors/track + diff --git a/tests/fixtures/centos-7.7/sfdisk-luM.out b/tests/fixtures/centos-7.7/sfdisk-luM.out new file mode 100644 index 00000000..574c5824 --- /dev/null +++ b/tests/fixtures/centos-7.7/sfdisk-luM.out @@ -0,0 +1,14 @@ + +Disk /dev/sda: 2610 cylinders, 255 heads, 63 sectors/track +Units: 1MiB = 1024*1024 bytes, blocks of 1024 bytes, counting from 0 + + Device Boot Start End MiB #blocks Id System +/dev/sda1 * 1 1024 1024 1048576 83 Linux +/dev/sda2 1025 20479 19455 19921920 8e Linux LVM +/dev/sda3 0 - 0 0 0 Empty +/dev/sda4 0 - 0 0 0 Empty + +Disk /dev/mapper/centos-root: 2218 cylinders, 255 heads, 63 sectors/track + +Disk /dev/mapper/centos-swap: 261 cylinders, 255 heads, 63 sectors/track + diff --git a/tests/fixtures/centos-7.7/sfdisk-luS.out b/tests/fixtures/centos-7.7/sfdisk-luS.out new file mode 100644 index 00000000..d2202d81 --- /dev/null +++ b/tests/fixtures/centos-7.7/sfdisk-luS.out @@ -0,0 +1,14 @@ + +Disk /dev/sda: 2610 cylinders, 255 heads, 63 sectors/track +Units: sectors of 512 bytes, counting from 0 + + Device Boot Start End #sectors Id System +/dev/sda1 * 2048 2099199 2097152 83 Linux +/dev/sda2 2099200 41943039 39843840 8e Linux LVM +/dev/sda3 0 - 0 0 Empty +/dev/sda4 0 - 0 0 Empty + +Disk /dev/mapper/centos-root: 2218 cylinders, 255 heads, 63 sectors/track + +Disk /dev/mapper/centos-swap: 261 cylinders, 255 heads, 63 sectors/track +