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:
@ -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
|
||||||
|
Reference in New Issue
Block a user