1
0
mirror of https://github.com/kellyjonbrazil/jc.git synced 2025-06-17 00:07:37 +02:00

finish use cases and doc

This commit is contained in:
Kelly Brazil
2022-02-24 20:31:58 -08:00
parent 7f409b7082
commit f4d11d697e

View File

@ -1,14 +1,21 @@
"""jc - JSON CLI output utility `nmcli` command output parser """jc - JSON CLI output utility `nmcli` command output parser
<<Short nmcli description and caveats>> Supports the following `nmcli` subcommands:
- `nmcli general`
- `nmcli general permissions`
- `nmcli connection`
- `nmcli connection show <device_name>`
- `nmcli device`
- `nmcli device show`
- `nmcli device show <device_name>`
Usage (cli): Usage (cli):
$ nmcli | jc --nmcli $ nmcli device show lo | jc --nmcli
or or
$ jc nmcli $ jc nmcli device show lo
Usage (module): Usage (module):
@ -22,26 +29,123 @@ Usage (module):
Schema: Schema:
Because there are so many options, the schema is best effort. Integer
and Float value conversions are attempted and the original values are
kept if they fail. If you don't want automatic conversion, then use the
-r or raw=True option to disable it.
The structure is flat, for the most part, but there are a couple of
"well-known" keys that are further parsed into objects for convenience.
These are documented below.
[ [
{ {
"nmcli": string, "<key>": string/integer/float, [0]
"bar": boolean, "dhcp4_option_x": {
"baz": integer "name": string,
"value": string/integer/float,
},
"ip4_route_x": {
"dst": string,
"nh": string,
"mt": integer
},
"ip6_route_x": {
"dst": string,
"nh": string,
"mt": integer,
"table": integer
}
} }
] ]
[0] all values of `---` are converted to null
Examples: Examples:
$ nmcli | jc --nmcli -p $ nmcli connection show ens33 | jc --nmcli -p
[] [
{
"connection_id": "ens33",
"connection_uuid": "d92ece08-9e02-47d5-b2d2-92c80e155744",
"connection_stable_id": null,
"connection_type": "802-3-ethernet",
"connection_interface_name": "ens33",
"connection_autoconnect": "yes",
...
"ip4_address_1": "192.168.71.180/24",
"ip4_gateway": "192.168.71.2",
"ip4_route_1": {
"dst": "0.0.0.0/0",
"nh": "192.168.71.2",
"mt": 100
},
"ip4_route_2": {
"dst": "192.168.71.0/24",
"nh": "0.0.0.0",
"mt": 100
},
"ip4_dns_1": "192.168.71.2",
"ip4_domain_1": "localdomain",
"dhcp4_option_1": {
"name": "broadcast_address",
"value": "192.168.71.255"
},
...
"ip6_address_1": "fe80::c1cb:715d:bc3e:b8a0/64",
"ip6_gateway": null,
"ip6_route_1": {
"dst": "fe80::/64",
"nh": "::",
"mt": 100
}
}
]
$ nmcli | jc --nmcli -p -r $ nmcli | jc --nmcli -p -r
[] [
{
"connection_id": "ens33",
"connection_uuid": "d92ece08-9e02-47d5-b2d2-92c80e155744",
"connection_stable_id": null,
"connection_type": "802-3-ethernet",
"connection_interface_name": "ens33",
"connection_autoconnect": "yes",
...
"ip4_address_1": "192.168.71.180/24",
"ip4_gateway": "192.168.71.2",
"ip4_route_1": {
"dst": "0.0.0.0/0",
"nh": "192.168.71.2",
"mt": "100"
},
"ip4_route_2": {
"dst": "192.168.71.0/24",
"nh": "0.0.0.0",
"mt": "100"
},
"ip4_dns_1": "192.168.71.2",
"ip4_domain_1": "localdomain",
"dhcp4_option_1": {
"name": "broadcast_address",
"value": "192.168.71.255"
},
...
"ip6_address_1": "fe80::c1cb:715d:bc3e:b8a0/64",
"ip6_gateway": null,
"ip6_route_1": {
"dst": "fe80::/64",
"nh": "::",
"mt": "100"
}
}
]
""" """
import re import re
from typing import List, Dict, Optional from typing import List, Dict, Optional
import jc.utils import jc.utils
from jc.parsers.universal import sparse_table_parse from jc.parsers.universal import sparse_table_parse
from jc.exceptions import ParseError
class info(): class info():
@ -70,10 +174,36 @@ def _process(proc_data: List[Dict]) -> List[Dict]:
List of Dictionaries. Structured to conform to the schema. List of Dictionaries. Structured to conform to the schema.
""" """
# process the data here for entry in proc_data:
# rebuild output for added semantic information for key in entry:
# use helper functions in jc.utils for int, float, bool # use normal int/float conversions since jc.utils.convert_to_int is too greedy
# conversions and timestamps try:
if '.' in entry[key]:
entry[key] = float(entry[key])
else:
entry[key] = int(entry[key])
except Exception:
pass
if '_option_' in key and key[-1].isdigit():
for k in entry[key]:
try:
if '.' in entry[key][k]:
entry[key][k] = float(entry[key][k])
else:
entry[key][k] = int(entry[key][k])
except Exception:
pass
if '_route_' in key and key[-1].isdigit():
for k in entry[key]:
try:
if '.' in entry[key][k]:
entry[key][k] = float(entry[key][k])
else:
entry[key][k] = int(entry[key][k])
except Exception:
pass
return proc_data return proc_data
@ -220,7 +350,17 @@ def _connection_show_x_parse(data: str) -> List[Dict]:
def _general_permissions_parse(data: str) -> List[Dict]: def _general_permissions_parse(data: str) -> List[Dict]:
print('general permissions') raw_output = []
output_dict = {}
for line in filter(None, data.splitlines()):
key, value = line.split()
key_n = _normalize_key(key)
output_dict[key_n] = value
output_dict.pop('permission')
raw_output.append(output_dict)
return raw_output
def _table_parse(data: str) -> List[Dict]: def _table_parse(data: str) -> List[Dict]:
@ -262,7 +402,7 @@ def parse(
# nmcli (second line startswith \t) # nmcli (second line startswith \t)
if data.splitlines()[1].startswith('\t'): if data.splitlines()[1].startswith('\t'):
print('nmcli only') raise ParseError('Use device, connection, or general subcommands in nmcli.')
# nmcli device show # nmcli device show
# nmcli device show lo # nmcli device show lo