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

Dev v1.23.4 (#439)

* version bump

* fix regex for crlf line endings

* Completed Ip_route parser (#429)

* tests

* Merge pull request #398 from kellyjonbrazil/dev

Dev v1.23.2

* Merge pull request #398 from kellyjonbrazil/dev

Dev v1.23.2

---------

Co-authored-by: Kelly Brazil <kellyjonbrazil@gmail.com>
Co-authored-by: Jjack3032 <julian.jackson@parsons.us>

* formatting

* doc update

* use splitlines

* formatting

* formatting

* Parser for `find` linux command (#434)

* Added find parser and tests for Centos 7.7 and Ubuntu 18.04

* Added a test file, changed logic, and included a case for permission denied returned by find.

* Added a few more lines to the tests

* Changed logic for setting values to null and updated test cases.

* doc update

* doc update

* Added proc_net_tcp parser (#421)

Co-authored-by: Kelly Brazil <kellyjonbrazil@gmail.com>

* clean up net_tcp parser

* add resolve.conf test files

* doc update

* add resolve.conf parser

* doc update

* add sortlist functionality

* add resolve.conf parser tests

* doc update

---------

Co-authored-by: Julian5555 <58196809+Julian5555@users.noreply.github.com>
Co-authored-by: Jjack3032 <julian.jackson@parsons.us>
Co-authored-by: solomonleang <124934439+solomonleang@users.noreply.github.com>
Co-authored-by: AlvinSolomon <41175627+AlvinSolomon@users.noreply.github.com>
This commit is contained in:
Kelly Brazil
2023-07-30 10:08:39 -07:00
committed by GitHub
parent d58ca402a7
commit 4cd721be85
42 changed files with 1645 additions and 11 deletions

View File

@ -1,5 +1,12 @@
jc changelog jc changelog
20230730 v1.23.4
- Add `/etc/resolve.conf` file parser
- Add `/proc/net/tcp` and `/proc/net/tcp6` file parser
- Add `find` command parser
- Add `ip route` command parser
- Fix `certbot` command parser to be more robust with different line endings
20230621 v1.23.3 20230621 v1.23.3
- Add `lsattr` command parser - Add `lsattr` command parser
- Add `srt` file parser - Add `srt` file parser
@ -13,7 +20,6 @@ jc changelog
- Enhance `ss` command parser to support extended options - Enhance `ss` command parser to support extended options
- Enhance the compatibility warning message - Enhance the compatibility warning message
- Fix `bluetoothctl` command parser for some mouse devices - Fix `bluetoothctl` command parser for some mouse devices
- Fix `certbot` command parser to be more robust with different line endings
- Fix `ping` command parsers for output with missing hostname - Fix `ping` command parsers for output with missing hostname
- Fix `stat` command parser for older versions that may not contain all fields - Fix `stat` command parser for older versions that may not contain all fields
- Fix deprecated option in `setup.cfg` - Fix deprecated option in `setup.cfg`

View File

@ -187,6 +187,7 @@ option.
| `--email-address` | Email Address string parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/email_address) | | `--email-address` | Email Address string parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/email_address) |
| `--env` | `env` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/env) | | `--env` | `env` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/env) |
| `--file` | `file` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/file) | | `--file` | `file` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/file) |
| `--find` | `find` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/find) |
| `--findmnt` | `findmnt` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/findmnt) | | `--findmnt` | `findmnt` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/findmnt) |
| `--finger` | `finger` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/finger) | | `--finger` | `finger` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/finger) |
| `--free` | `free` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/free) | | `--free` | `free` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/free) |
@ -210,6 +211,7 @@ option.
| `--iostat-s` | `iostat` command streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/iostat_s) | | `--iostat-s` | `iostat` command streaming parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/iostat_s) |
| `--ip-address` | IPv4 and IPv6 Address string parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ip_address) | | `--ip-address` | IPv4 and IPv6 Address string parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ip_address) |
| `--iptables` | `iptables` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/iptables) | | `--iptables` | `iptables` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/iptables) |
| `--ip-route` | `ip route` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ip_route) |
| `--iw-scan` | `iw dev [device] scan` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/iw_scan) | | `--iw-scan` | `iw dev [device] scan` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/iw_scan) |
| `--iwconfig` | `iwconfig` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/iwconfig) | | `--iwconfig` | `iwconfig` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/iwconfig) |
| `--jar-manifest` | Java MANIFEST.MF file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/jar_manifest) | | `--jar-manifest` | Java MANIFEST.MF file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/jar_manifest) |
@ -248,6 +250,7 @@ option.
| `--postconf` | `postconf -M` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/postconf) | | `--postconf` | `postconf -M` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/postconf) |
| `--proc` | `/proc/` file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/proc) | | `--proc` | `/proc/` file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/proc) |
| `--ps` | `ps` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ps) | | `--ps` | `ps` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/ps) |
| `--resolve-conf` | `/etc/resolve.conf` file parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/resolve_conf) |
| `--route` | `route` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/route) | | `--route` | `route` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/route) |
| `--rpm-qi` | `rpm -qi` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/rpm_qi) | | `--rpm-qi` | `rpm -qi` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/rpm_qi) |
| `--rsync` | `rsync` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/rsync) | | `--rsync` | `rsync` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/rsync) |

View File

@ -3,8 +3,8 @@ _jc()
local cur prev words cword jc_commands jc_parsers jc_options \ local cur prev words cword jc_commands jc_parsers jc_options \
jc_about_options jc_about_mod_options jc_help_options jc_special_options jc_about_options jc_about_mod_options jc_help_options jc_special_options
jc_commands=(acpi airport arp blkid bluetoothctl cbt certbot chage cksum crontab date df dig dmidecode dpkg du env file findmnt finger free git gpg hciconfig id ifconfig iostat iptables iw iwconfig jobs last lastb ls lsattr lsblk lsmod lsof lspci lsusb md5 md5sum mdadm mount mpstat netstat nmcli ntpq os-prober pidstat ping ping6 pip pip3 postconf printenv ps route rpm rsync sfdisk sha1sum sha224sum sha256sum sha384sum sha512sum shasum ss ssh sshd stat sum sysctl systemctl systeminfo timedatectl top tracepath tracepath6 traceroute traceroute6 udevadm ufw uname update-alternatives upower uptime vdir veracrypt vmstat w wc who xrandr zipinfo zpool) jc_commands=(acpi airport arp blkid bluetoothctl cbt certbot chage cksum crontab date df dig dmidecode dpkg du env file findmnt finger free git gpg hciconfig id ifconfig iostat ip iptables iw iwconfig jobs last lastb ls lsattr lsblk lsmod lsof lspci lsusb md5 md5sum mdadm mount mpstat netstat nmcli ntpq os-prober pidstat ping ping6 pip pip3 postconf printenv ps route rpm rsync sfdisk sha1sum sha224sum sha256sum sha384sum sha512sum shasum ss ssh sshd stat sum sysctl systemctl systeminfo timedatectl top tracepath tracepath6 traceroute traceroute6 udevadm ufw uname update-alternatives upower uptime vdir veracrypt vmstat w wc who xrandr zipinfo zpool)
jc_parsers=(--acpi --airport --airport-s --arp --asciitable --asciitable-m --blkid --bluetoothctl --cbt --cef --cef-s --certbot --chage --cksum --clf --clf-s --crontab --crontab-u --csv --csv-s --date --datetime-iso --df --dig --dir --dmidecode --dpkg-l --du --email-address --env --file --findmnt --finger --free --fstab --git-log --git-log-s --git-ls-remote --gpg --group --gshadow --hash --hashsum --hciconfig --history --hosts --id --ifconfig --ini --ini-dup --iostat --iostat-s --ip-address --iptables --iw-scan --iwconfig --jar-manifest --jobs --jwt --kv --last --ls --ls-s --lsattr --lsblk --lsmod --lsof --lspci --lsusb --m3u --mdadm --mount --mpstat --mpstat-s --netstat --nmcli --ntpq --openvpn --os-prober --passwd --pci-ids --pgpass --pidstat --pidstat-s --ping --ping-s --pip-list --pip-show --plist --postconf --proc --proc-buddyinfo --proc-consoles --proc-cpuinfo --proc-crypto --proc-devices --proc-diskstats --proc-filesystems --proc-interrupts --proc-iomem --proc-ioports --proc-loadavg --proc-locks --proc-meminfo --proc-modules --proc-mtrr --proc-pagetypeinfo --proc-partitions --proc-slabinfo --proc-softirqs --proc-stat --proc-swaps --proc-uptime --proc-version --proc-vmallocinfo --proc-vmstat --proc-zoneinfo --proc-driver-rtc --proc-net-arp --proc-net-dev --proc-net-dev-mcast --proc-net-if-inet6 --proc-net-igmp --proc-net-igmp6 --proc-net-ipv6-route --proc-net-netlink --proc-net-netstat --proc-net-packet --proc-net-protocols --proc-net-route --proc-net-unix --proc-pid-fdinfo --proc-pid-io --proc-pid-maps --proc-pid-mountinfo --proc-pid-numa-maps --proc-pid-smaps --proc-pid-stat --proc-pid-statm --proc-pid-status --ps --route --rpm-qi --rsync --rsync-s --semver --sfdisk --shadow --srt --ss --ssh-conf --sshd-conf --stat --stat-s --sysctl --syslog --syslog-s --syslog-bsd --syslog-bsd-s --systemctl --systemctl-lj --systemctl-ls --systemctl-luf --systeminfo --time --timedatectl --timestamp --toml --top --top-s --tracepath --traceroute --udevadm --ufw --ufw-appinfo --uname --update-alt-gs --update-alt-q --upower --uptime --url --ver --veracrypt --vmstat --vmstat-s --w --wc --who --x509-cert --x509-csr --xml --xrandr --yaml --zipinfo --zpool-iostat --zpool-status) jc_parsers=(--acpi --airport --airport-s --arp --asciitable --asciitable-m --blkid --bluetoothctl --cbt --cef --cef-s --certbot --chage --cksum --clf --clf-s --crontab --crontab-u --csv --csv-s --date --datetime-iso --df --dig --dir --dmidecode --dpkg-l --du --email-address --env --file --find --findmnt --finger --free --fstab --git-log --git-log-s --git-ls-remote --gpg --group --gshadow --hash --hashsum --hciconfig --history --hosts --id --ifconfig --ini --ini-dup --iostat --iostat-s --ip-address --iptables --ip-route --iw-scan --iwconfig --jar-manifest --jobs --jwt --kv --last --ls --ls-s --lsattr --lsblk --lsmod --lsof --lspci --lsusb --m3u --mdadm --mount --mpstat --mpstat-s --netstat --nmcli --ntpq --openvpn --os-prober --passwd --pci-ids --pgpass --pidstat --pidstat-s --ping --ping-s --pip-list --pip-show --plist --postconf --proc --proc-buddyinfo --proc-consoles --proc-cpuinfo --proc-crypto --proc-devices --proc-diskstats --proc-filesystems --proc-interrupts --proc-iomem --proc-ioports --proc-loadavg --proc-locks --proc-meminfo --proc-modules --proc-mtrr --proc-pagetypeinfo --proc-partitions --proc-slabinfo --proc-softirqs --proc-stat --proc-swaps --proc-uptime --proc-version --proc-vmallocinfo --proc-vmstat --proc-zoneinfo --proc-driver-rtc --proc-net-arp --proc-net-dev --proc-net-dev-mcast --proc-net-if-inet6 --proc-net-igmp --proc-net-igmp6 --proc-net-ipv6-route --proc-net-netlink --proc-net-netstat --proc-net-packet --proc-net-protocols --proc-net-route --proc-net-tcp --proc-net-unix --proc-pid-fdinfo --proc-pid-io --proc-pid-maps --proc-pid-mountinfo --proc-pid-numa-maps --proc-pid-smaps --proc-pid-stat --proc-pid-statm --proc-pid-status --ps --resolve-conf --route --rpm-qi --rsync --rsync-s --semver --sfdisk --shadow --srt --ss --ssh-conf --sshd-conf --stat --stat-s --sysctl --syslog --syslog-s --syslog-bsd --syslog-bsd-s --systemctl --systemctl-lj --systemctl-ls --systemctl-luf --systeminfo --time --timedatectl --timestamp --toml --top --top-s --tracepath --traceroute --udevadm --ufw --ufw-appinfo --uname --update-alt-gs --update-alt-q --upower --uptime --url --ver --veracrypt --vmstat --vmstat-s --w --wc --who --x509-cert --x509-csr --xml --xrandr --yaml --zipinfo --zpool-iostat --zpool-status)
jc_options=(--force-color -C --debug -d --monochrome -m --meta-out -M --pretty -p --quiet -q --raw -r --unbuffer -u --yaml-out -y) jc_options=(--force-color -C --debug -d --monochrome -m --meta-out -M --pretty -p --quiet -q --raw -r --unbuffer -u --yaml-out -y)
jc_about_options=(--about -a) jc_about_options=(--about -a)
jc_about_mod_options=(--pretty -p --yaml-out -y --monochrome -m --force-color -C) jc_about_mod_options=(--pretty -p --yaml-out -y --monochrome -m --force-color -C)

View File

@ -9,7 +9,7 @@ _jc() {
jc_help_options jc_help_options_describe \ jc_help_options jc_help_options_describe \
jc_special_options jc_special_options_describe jc_special_options jc_special_options_describe
jc_commands=(acpi airport arp blkid bluetoothctl cbt certbot chage cksum crontab date df dig dmidecode dpkg du env file findmnt finger free git gpg hciconfig id ifconfig iostat iptables iw iwconfig jobs last lastb ls lsattr lsblk lsmod lsof lspci lsusb md5 md5sum mdadm mount mpstat netstat nmcli ntpq os-prober pidstat ping ping6 pip pip3 postconf printenv ps route rpm rsync sfdisk sha1sum sha224sum sha256sum sha384sum sha512sum shasum ss ssh sshd stat sum sysctl systemctl systeminfo timedatectl top tracepath tracepath6 traceroute traceroute6 udevadm ufw uname update-alternatives upower uptime vdir veracrypt vmstat w wc who xrandr zipinfo zpool) jc_commands=(acpi airport arp blkid bluetoothctl cbt certbot chage cksum crontab date df dig dmidecode dpkg du env file findmnt finger free git gpg hciconfig id ifconfig iostat ip iptables iw iwconfig jobs last lastb ls lsattr lsblk lsmod lsof lspci lsusb md5 md5sum mdadm mount mpstat netstat nmcli ntpq os-prober pidstat ping ping6 pip pip3 postconf printenv ps route rpm rsync sfdisk sha1sum sha224sum sha256sum sha384sum sha512sum shasum ss ssh sshd stat sum sysctl systemctl systeminfo timedatectl top tracepath tracepath6 traceroute traceroute6 udevadm ufw uname update-alternatives upower uptime vdir veracrypt vmstat w wc who xrandr zipinfo zpool)
jc_commands_describe=( jc_commands_describe=(
'acpi:run "acpi" command with magic syntax.' 'acpi:run "acpi" command with magic syntax.'
'airport:run "airport" command with magic syntax.' 'airport:run "airport" command with magic syntax.'
@ -38,6 +38,7 @@ _jc() {
'id:run "id" command with magic syntax.' 'id:run "id" command with magic syntax.'
'ifconfig:run "ifconfig" command with magic syntax.' 'ifconfig:run "ifconfig" command with magic syntax.'
'iostat:run "iostat" command with magic syntax.' 'iostat:run "iostat" command with magic syntax.'
'ip:run "ip" command with magic syntax.'
'iptables:run "iptables" command with magic syntax.' 'iptables:run "iptables" command with magic syntax.'
'iw:run "iw" command with magic syntax.' 'iw:run "iw" command with magic syntax.'
'iwconfig:run "iwconfig" command with magic syntax.' 'iwconfig:run "iwconfig" command with magic syntax.'
@ -108,7 +109,7 @@ _jc() {
'zipinfo:run "zipinfo" command with magic syntax.' 'zipinfo:run "zipinfo" command with magic syntax.'
'zpool:run "zpool" command with magic syntax.' 'zpool:run "zpool" command with magic syntax.'
) )
jc_parsers=(--acpi --airport --airport-s --arp --asciitable --asciitable-m --blkid --bluetoothctl --cbt --cef --cef-s --certbot --chage --cksum --clf --clf-s --crontab --crontab-u --csv --csv-s --date --datetime-iso --df --dig --dir --dmidecode --dpkg-l --du --email-address --env --file --findmnt --finger --free --fstab --git-log --git-log-s --git-ls-remote --gpg --group --gshadow --hash --hashsum --hciconfig --history --hosts --id --ifconfig --ini --ini-dup --iostat --iostat-s --ip-address --iptables --iw-scan --iwconfig --jar-manifest --jobs --jwt --kv --last --ls --ls-s --lsattr --lsblk --lsmod --lsof --lspci --lsusb --m3u --mdadm --mount --mpstat --mpstat-s --netstat --nmcli --ntpq --openvpn --os-prober --passwd --pci-ids --pgpass --pidstat --pidstat-s --ping --ping-s --pip-list --pip-show --plist --postconf --proc --proc-buddyinfo --proc-consoles --proc-cpuinfo --proc-crypto --proc-devices --proc-diskstats --proc-filesystems --proc-interrupts --proc-iomem --proc-ioports --proc-loadavg --proc-locks --proc-meminfo --proc-modules --proc-mtrr --proc-pagetypeinfo --proc-partitions --proc-slabinfo --proc-softirqs --proc-stat --proc-swaps --proc-uptime --proc-version --proc-vmallocinfo --proc-vmstat --proc-zoneinfo --proc-driver-rtc --proc-net-arp --proc-net-dev --proc-net-dev-mcast --proc-net-if-inet6 --proc-net-igmp --proc-net-igmp6 --proc-net-ipv6-route --proc-net-netlink --proc-net-netstat --proc-net-packet --proc-net-protocols --proc-net-route --proc-net-unix --proc-pid-fdinfo --proc-pid-io --proc-pid-maps --proc-pid-mountinfo --proc-pid-numa-maps --proc-pid-smaps --proc-pid-stat --proc-pid-statm --proc-pid-status --ps --route --rpm-qi --rsync --rsync-s --semver --sfdisk --shadow --srt --ss --ssh-conf --sshd-conf --stat --stat-s --sysctl --syslog --syslog-s --syslog-bsd --syslog-bsd-s --systemctl --systemctl-lj --systemctl-ls --systemctl-luf --systeminfo --time --timedatectl --timestamp --toml --top --top-s --tracepath --traceroute --udevadm --ufw --ufw-appinfo --uname --update-alt-gs --update-alt-q --upower --uptime --url --ver --veracrypt --vmstat --vmstat-s --w --wc --who --x509-cert --x509-csr --xml --xrandr --yaml --zipinfo --zpool-iostat --zpool-status) jc_parsers=(--acpi --airport --airport-s --arp --asciitable --asciitable-m --blkid --bluetoothctl --cbt --cef --cef-s --certbot --chage --cksum --clf --clf-s --crontab --crontab-u --csv --csv-s --date --datetime-iso --df --dig --dir --dmidecode --dpkg-l --du --email-address --env --file --find --findmnt --finger --free --fstab --git-log --git-log-s --git-ls-remote --gpg --group --gshadow --hash --hashsum --hciconfig --history --hosts --id --ifconfig --ini --ini-dup --iostat --iostat-s --ip-address --iptables --ip-route --iw-scan --iwconfig --jar-manifest --jobs --jwt --kv --last --ls --ls-s --lsattr --lsblk --lsmod --lsof --lspci --lsusb --m3u --mdadm --mount --mpstat --mpstat-s --netstat --nmcli --ntpq --openvpn --os-prober --passwd --pci-ids --pgpass --pidstat --pidstat-s --ping --ping-s --pip-list --pip-show --plist --postconf --proc --proc-buddyinfo --proc-consoles --proc-cpuinfo --proc-crypto --proc-devices --proc-diskstats --proc-filesystems --proc-interrupts --proc-iomem --proc-ioports --proc-loadavg --proc-locks --proc-meminfo --proc-modules --proc-mtrr --proc-pagetypeinfo --proc-partitions --proc-slabinfo --proc-softirqs --proc-stat --proc-swaps --proc-uptime --proc-version --proc-vmallocinfo --proc-vmstat --proc-zoneinfo --proc-driver-rtc --proc-net-arp --proc-net-dev --proc-net-dev-mcast --proc-net-if-inet6 --proc-net-igmp --proc-net-igmp6 --proc-net-ipv6-route --proc-net-netlink --proc-net-netstat --proc-net-packet --proc-net-protocols --proc-net-route --proc-net-tcp --proc-net-unix --proc-pid-fdinfo --proc-pid-io --proc-pid-maps --proc-pid-mountinfo --proc-pid-numa-maps --proc-pid-smaps --proc-pid-stat --proc-pid-statm --proc-pid-status --ps --resolve-conf --route --rpm-qi --rsync --rsync-s --semver --sfdisk --shadow --srt --ss --ssh-conf --sshd-conf --stat --stat-s --sysctl --syslog --syslog-s --syslog-bsd --syslog-bsd-s --systemctl --systemctl-lj --systemctl-ls --systemctl-luf --systeminfo --time --timedatectl --timestamp --toml --top --top-s --tracepath --traceroute --udevadm --ufw --ufw-appinfo --uname --update-alt-gs --update-alt-q --upower --uptime --url --ver --veracrypt --vmstat --vmstat-s --w --wc --who --x509-cert --x509-csr --xml --xrandr --yaml --zipinfo --zpool-iostat --zpool-status)
jc_parsers_describe=( jc_parsers_describe=(
'--acpi:`acpi` command parser' '--acpi:`acpi` command parser'
'--airport:`airport -I` command parser' '--airport:`airport -I` command parser'
@ -141,6 +142,7 @@ _jc() {
'--email-address:Email Address string parser' '--email-address:Email Address string parser'
'--env:`env` command parser' '--env:`env` command parser'
'--file:`file` command parser' '--file:`file` command parser'
'--find:`find` command parser'
'--findmnt:`findmnt` command parser' '--findmnt:`findmnt` command parser'
'--finger:`finger` command parser' '--finger:`finger` command parser'
'--free:`free` command parser' '--free:`free` command parser'
@ -164,6 +166,7 @@ _jc() {
'--iostat-s:`iostat` command streaming parser' '--iostat-s:`iostat` command streaming parser'
'--ip-address:IPv4 and IPv6 Address string parser' '--ip-address:IPv4 and IPv6 Address string parser'
'--iptables:`iptables` command parser' '--iptables:`iptables` command parser'
'--ip-route:`ip route` command parser'
'--iw-scan:`iw dev [device] scan` command parser' '--iw-scan:`iw dev [device] scan` command parser'
'--iwconfig:`iwconfig` command parser' '--iwconfig:`iwconfig` command parser'
'--jar-manifest:Java MANIFEST.MF file parser' '--jar-manifest:Java MANIFEST.MF file parser'
@ -240,6 +243,7 @@ _jc() {
'--proc-net-packet:`/proc/net/packet` file parser' '--proc-net-packet:`/proc/net/packet` file parser'
'--proc-net-protocols:`/proc/net/protocols` file parser' '--proc-net-protocols:`/proc/net/protocols` file parser'
'--proc-net-route:`/proc/net/route` file parser' '--proc-net-route:`/proc/net/route` file parser'
'--proc-net-tcp:`/proc/net/tcp` and `/proc/net/tcp6` file parser'
'--proc-net-unix:`/proc/net/unix` file parser' '--proc-net-unix:`/proc/net/unix` file parser'
'--proc-pid-fdinfo:`/proc/<pid>/fdinfo/<fd>` file parser' '--proc-pid-fdinfo:`/proc/<pid>/fdinfo/<fd>` file parser'
'--proc-pid-io:`/proc/<pid>/io` file parser' '--proc-pid-io:`/proc/<pid>/io` file parser'
@ -251,6 +255,7 @@ _jc() {
'--proc-pid-statm:`/proc/<pid>/statm` file parser' '--proc-pid-statm:`/proc/<pid>/statm` file parser'
'--proc-pid-status:`/proc/<pid>/status` file parser' '--proc-pid-status:`/proc/<pid>/status` file parser'
'--ps:`ps` command parser' '--ps:`ps` command parser'
'--resolve-conf:`/etc/resolve.conf` file parser'
'--route:`route` command parser' '--route:`route` command parser'
'--rpm-qi:`rpm -qi` command parser' '--rpm-qi:`rpm -qi` command parser'
'--rsync:`rsync` command parser' '--rsync:`rsync` command parser'

View File

@ -158,4 +158,4 @@ Returns:
### Parser Information ### Parser Information
Compatibility: linux, darwin, cygwin, win32, aix, freebsd Compatibility: linux, darwin, cygwin, win32, aix, freebsd
Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com) Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com)

82
docs/parsers/find.md Normal file
View File

@ -0,0 +1,82 @@
[Home](https://kellyjonbrazil.github.io/jc/)
<a id="jc.parsers.find"></a>
# jc.parsers.find
jc - JSON Convert `find` command output parser
This parser returns a list of objects by default and a list of strings if
the `--raw` option is used.
Usage (cli):
$ find | jc --find
Usage (module):
import jc
result = jc.parse('find', find_command_output)
Schema:
[
{
"path": string,
"node": string,
"error": string
}
]
Examples:
$ find | jc --find -p
[
{
"path": "./directory"
"node": "filename"
},
{
"path": "./anotherdirectory"
"node": "anotherfile"
},
{
"path": null
"node": null
"error": "find: './inaccessible': Permission denied"
}
...
]
$ find | jc --find -p -r
[
"./templates/readme_template",
"./templates/manpage_template",
"./.github/workflows/pythonapp.yml",
...
]
<a id="jc.parsers.find.parse"></a>
### parse
```python
def parse(data, raw=False, quiet=False)
```
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:
List of raw strings or
List of Dictionaries of processed structured data
### Parser Information
Compatibility: linux
Version 1.0 by Solomon Leang (solomonleang@gmail.com)

74
docs/parsers/ip_route.md Normal file
View File

@ -0,0 +1,74 @@
[Home](https://kellyjonbrazil.github.io/jc/)
<a id="jc.parsers.ip_route"></a>
# jc.parsers.ip\_route
jc - JSON Convert `ip route` command output parser
Usage (cli):
$ ip route | jc --ip-route
or
$ jc ip-route
Usage (module):
import jc
result = jc.parse('ip_route', ip_route_command_output)
Schema:
[
{
"ip": string,
"via": string,
"dev": string,
"metric": integer,
"proto": string,
"scope": string,
"src": string,
"via": string,
"status": string
}
]
Examples:
$ ip route | jc --ip-route -p
[
{
"ip": "10.0.2.0/24",
"dev": "enp0s3",
"proto": "kernel",
"scope": "link",
"src": "10.0.2.15",
"metric": 100
}
]
<a id="jc.parsers.ip_route.parse"></a>
### parse
```python
def parse(data, raw=False, quiet=False)
```
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:
List of Json objects if data is processed and Raw data if raw = true.
### Parser Information
Compatibility: linux
Version 1.0 by Julian Jackson (jackson.julian55@yahoo.com)

View File

@ -0,0 +1,186 @@
[Home](https://kellyjonbrazil.github.io/jc/)
<a id="jc.parsers.proc_net_tcp"></a>
# jc.parsers.proc\_net\_tcp
jc - JSON Convert `/proc/net/tcp` and `proc/net/tcp6` file parser
IPv4 and IPv6 addresses are converted to standard notation unless the raw
(--raw) option is used.
Usage (cli):
$ cat /proc/net/tcp | jc --proc
or
$ jc /proc/net/tcp
or
$ cat /proc/net/tcp | jc --proc-net-tcp
Usage (module):
import jc
result = jc.parse('proc', proc_net_tcp_file)
or
import jc
result = jc.parse('proc_net_tcp', proc_net_tcp_file)
Schema:
Field names and types gathered from the following:
https://www.kernel.org/doc/Documentation/networking/proc_net_tcp.txt
https://github.com/torvalds/linux/blob/master/net/ipv4/tcp_ipv4.c
https://github.com/torvalds/linux/blob/master/net/ipv6/tcp_ipv6.c
[
{
"entry": integer,
"local_address": string,
"local_port": integer,
"remote_address": string,
"remote_port": integer,
"state": string,
"tx_queue": string,
"rx_queue": string,
"timer_active": integer,
"jiffies_until_timer_expires": string,
"unrecovered_rto_timeouts": string,
"uid": integer,
"unanswered_0_window_probes": integer,
"inode": integer,
"sock_ref_count": integer,
"sock_mem_loc": string,
"retransmit_timeout": integer,
"soft_clock_tick": integer,
"ack_quick_pingpong": integer,
"sending_congestion_window": integer,
"slow_start_size_threshold": integer
}
]
Examples:
$ cat /proc/net/tcp | jc --proc -p
[
{
"entry": "0",
"local_address": "10.0.0.28",
"local_port": 42082,
"remote_address": "64.12.0.108",
"remote_port": 80,
"state": "04",
"tx_queue": "00000001",
"rx_queue": "00000000",
"timer_active": 1,
"jiffies_until_timer_expires": "00000015",
"unrecovered_rto_timeouts": "00000000",
"uid": 0,
"unanswered_0_window_probes": 0,
"inode": 0,
"sock_ref_count": 3,
"sock_mem_loc": "ffff8c7a0de930c0",
"retransmit_timeout": 21,
"soft_clock_tick": 4,
"ack_quick_pingpong": 30,
"sending_congestion_window": 10,
"slow_start_size_threshold": -1
},
{
"entry": "1",
"local_address": "10.0.0.28",
"local_port": 38864,
"remote_address": "104.244.42.65",
"remote_port": 80,
"state": "06",
"tx_queue": "00000000",
"rx_queue": "00000000",
"timer_active": 3,
"jiffies_until_timer_expires": "000007C5",
"unrecovered_rto_timeouts": "00000000",
"uid": 0,
"unanswered_0_window_probes": 0,
"inode": 0,
"sock_ref_count": 3,
"sock_mem_loc": "ffff8c7a12d31aa0"
},
...
]
$ cat /proc/net/tcp | jc --proc -p -r
[
{
"entry": "1",
"local_address": "1C00000A",
"local_port": "A462",
"remote_address": "6C000C40",
"remote_port": "0050",
"state": "04",
"tx_queue": "00000001",
"rx_queue": "00000000",
"timer_active": "01",
"jiffies_until_timer_expires": "00000015",
"unrecovered_rto_timeouts": "00000000",
"uid": "0",
"unanswered_0_window_probes": "0",
"inode": "0",
"sock_ref_count": "3",
"sock_mem_loc": "ffff8c7a0de930c0",
"retransmit_timeout": "21",
"soft_clock_tick": "4",
"ack_quick_pingpong": "30",
"sending_congestion_window": "10",
"slow_start_size_threshold": "-1"
},
{
"entry": "2",
"local_address": "1C00000A",
"local_port": "97D0",
"remote_address": "412AF468",
"remote_port": "0050",
"state": "06",
"tx_queue": "00000000",
"rx_queue": "00000000",
"timer_active": "03",
"jiffies_until_timer_expires": "000007C5",
"unrecovered_rto_timeouts": "00000000",
"uid": "0",
"unanswered_0_window_probes": "0",
"inode": "0",
"sock_ref_count": "3",
"sock_mem_loc": "ffff8c7a12d31aa0"
},
...
]
<a id="jc.parsers.proc_net_tcp.parse"></a>
### parse
```python
def parse(data: str, raw: bool = False, quiet: bool = False) -> List[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:
List of Dictionaries. Raw or processed structured data.
### Parser Information
Compatibility: linux
Version 1.0 by Alvin Solomon (alvinms01@gmail.com)

View File

@ -0,0 +1,83 @@
[Home](https://kellyjonbrazil.github.io/jc/)
<a id="jc.parsers.resolve_conf"></a>
# jc.parsers.resolve\_conf
jc - JSON Convert `/etc/resolve.conf` file parser
This parser may be more forgiving than the system parser. For example, if
multiple `search` lists are defined, this parser will append all entries to
the `search` field, while the system parser may only use the list from the
last defined instance.
Usage (cli):
$ cat /etc/resolve.conf | jc --resolve-conf
Usage (module):
import jc
result = jc.parse('resolve_conf', resolve_conf_output)
Schema:
{
"domain": string,
"search": [
string
],
"nameservers": [
string
],
"options": [
string
],
"sortlist": [
string
]
}
Examples:
$ cat /etc/resolve.conf | jc --resolve-conf -p
{
"search": [
"eng.myprime.com",
"dev.eng.myprime.com",
"labs.myprime.com",
"qa.myprime.com"
],
"nameservers": [
"10.136.17.15"
],
"options": [
"rotate",
"ndots:1"
]
}
<a id="jc.parsers.resolve_conf.parse"></a>
### parse
```python
def parse(data: str, raw: bool = False, quiet: bool = False) -> JSONDictType
```
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.
### Parser Information
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com)

View File

@ -9,7 +9,7 @@ from .jc_types import ParserInfoType, JSONDictType
from jc import appdirs from jc import appdirs
__version__ = '1.23.3' __version__ = '1.23.4'
parsers: List[str] = [ parsers: List[str] = [
'acpi', 'acpi',
@ -43,6 +43,7 @@ parsers: List[str] = [
'email-address', 'email-address',
'env', 'env',
'file', 'file',
'find',
'findmnt', 'findmnt',
'finger', 'finger',
'free', 'free',
@ -66,6 +67,7 @@ parsers: List[str] = [
'iostat-s', 'iostat-s',
'ip-address', 'ip-address',
'iptables', 'iptables',
'ip-route',
'iso-datetime', 'iso-datetime',
'iw-scan', 'iw-scan',
'iwconfig', 'iwconfig',
@ -143,6 +145,7 @@ parsers: List[str] = [
'proc-net-packet', 'proc-net-packet',
'proc-net-protocols', 'proc-net-protocols',
'proc-net-route', 'proc-net-route',
'proc-net-tcp',
'proc-net-unix', 'proc-net-unix',
'proc-pid-fdinfo', 'proc-pid-fdinfo',
'proc-pid-io', 'proc-pid-io',
@ -154,6 +157,7 @@ parsers: List[str] = [
'proc-pid-statm', 'proc-pid-statm',
'proc-pid-status', 'proc-pid-status',
'ps', 'ps',
'resolve-conf',
'route', 'route',
'rpm-qi', 'rpm-qi',
'rsync', 'rsync',

View File

@ -138,7 +138,7 @@ import jc.utils
class info(): class info():
"""Provides parser metadata (version, author, etc.)""" """Provides parser metadata (version, author, etc.)"""
version = '1.1' version = '1.2'
description = '`certbot` command parser' description = '`certbot` command parser'
author = 'Kelly Brazil' author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com' author_email = 'kellyjonbrazil@gmail.com'
@ -201,7 +201,7 @@ def parse(
if jc.utils.has_data(data): if jc.utils.has_data(data):
cert_pattern = re.compile(r'^Found the following certs:$', re.MULTILINE) cert_pattern = re.compile(r'^Found the following certs:\r?$', re.MULTILINE)
if re.search(cert_pattern, data): if re.search(cert_pattern, data):
cmd_option = 'certificates' cmd_option = 'certificates'

137
jc/parsers/find.py Normal file
View File

@ -0,0 +1,137 @@
"""jc - JSON Convert `find` command output parser
This parser returns a list of objects by default and a list of strings if
the `--raw` option is used.
Usage (cli):
$ find | jc --find
Usage (module):
import jc
result = jc.parse('find', find_command_output)
Schema:
[
{
"path": string,
"node": string,
"error": string
}
]
Examples:
$ find | jc --find -p
[
{
"path": "./directory"
"node": "filename"
},
{
"path": "./anotherdirectory"
"node": "anotherfile"
},
{
"path": null
"node": null
"error": "find: './inaccessible': Permission denied"
}
...
]
$ find | jc --find -p -r
[
"./templates/readme_template",
"./templates/manpage_template",
"./.github/workflows/pythonapp.yml",
...
]
"""
import jc.utils
class info():
"""Provides parser metadata (version, author, etc.)"""
version = '1.0'
description = '`find` command parser'
author = 'Solomon Leang'
author_email = 'solomonleang@gmail.com'
compatible = ['linux']
tags = ['command']
__version__ = info.version
def _process(proc_data):
"""
Final processing to conform to the schema.
Parameters:
proc_data: (List of Strings) raw structured data to process
Returns:
List of Dictionaries. Structured data to conform to the schema.
"""
processed = []
for index in proc_data:
path, node, error = "", "", ""
if index == ".":
node = "."
elif index.startswith('find: '):
error = index
else:
try:
path, node = index.rsplit('/', maxsplit=1)
except ValueError:
pass
proc_line = {
'path': path if path else None,
'node': node if node else None
}
if error:
proc_line.update(
{'error': error}
)
processed.append(proc_line)
return processed
def parse(data, raw=False, quiet=False):
"""
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:
List of raw strings or
List of Dictionaries of processed structured data
"""
jc.utils.compatibility(__name__, info.compatible, quiet)
jc.utils.input_type_check(data)
raw_output = []
if jc.utils.has_data(data):
raw_output = data.splitlines()
if raw:
return raw_output
else:
return _process(raw_output)

145
jc/parsers/ip_route.py Normal file
View File

@ -0,0 +1,145 @@
"""jc - JSON Convert `ip route` command output parser
Usage (cli):
$ ip route | jc --ip-route
or
$ jc ip-route
Usage (module):
import jc
result = jc.parse('ip_route', ip_route_command_output)
Schema:
[
{
"ip": string,
"via": string,
"dev": string,
"metric": integer,
"proto": string,
"scope": string,
"src": string,
"via": string,
"status": string
}
]
Examples:
$ ip route | jc --ip-route -p
[
{
"ip": "10.0.2.0/24",
"dev": "enp0s3",
"proto": "kernel",
"scope": "link",
"src": "10.0.2.15",
"metric": 100
}
]
"""
from typing import Dict
import jc.utils
class info:
"""Provides parser metadata (version, author, etc.)"""
version = '1.0'
description = '`ip route` command parser'
author = 'Julian Jackson'
author_email = 'jackson.julian55@yahoo.com'
compatible = ['linux']
magic_commands = ['ip route']
tags = ['command']
__version__ = info.version
def parse(data, raw=False, quiet=False):
"""
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:
List of Json objects if data is processed and Raw data if raw = true.
"""
structure = {}
items = []
lines = data.splitlines()
index = 0
place = 0
inc = 0
for line in lines:
temp = line.split()
for word in temp:
if word == 'via':
y = {'via': temp[place + 1]}
place += 1
structure.update(y)
elif word == 'dev':
y = {'dev': temp[place + 1]}
place += 1
structure.update(y)
elif word == 'metric':
if raw:
y = {'metric': temp[place + 1]}
else:
y = {'metric': jc.utils.convert_to_int(temp[place+1])}
place += 1
structure.update(y)
elif word == 'proto':
y = {'proto': temp[place + 1]}
place += 1
structure.update(y)
elif word == 'scope':
y = {'scope': temp[place + 1]}
place += 1
structure.update(y)
elif word == 'src':
y = {'src': temp[place + 1]}
place += 1
structure.update(y)
elif word == 'status':
y = {'status': temp[place + 1]}
place += 1
structure.update(y)
elif word == 'default':
y = {'ip': 'default'}
place += 1
structure.update(y)
elif word == 'linkdown':
y = {'status': 'linkdown'}
place += 1
structure.update(y)
else:
y = {'ip': temp[0]}
place += 1
structure.update(y)
if y.get("ip") != "":
items.append(structure)
structure = {}
place = 0
index += 1
inc += 1
jc.utils.compatibility(__name__, info.compatible, quiet)
jc.utils.input_type_check(data)
if not jc.utils.has_data(data):
return []
return items

View File

@ -194,6 +194,7 @@ def parse(
net_packet_p = re.compile(r'^sk RefCnt Type Proto Iface R Rmem User Inode\n') net_packet_p = re.compile(r'^sk RefCnt Type Proto Iface R Rmem User Inode\n')
net_protocols_p = re.compile(r'^protocol size sockets memory press maxhdr slab module cl co di ac io in de sh ss gs se re sp bi br ha uh gp em\n') net_protocols_p = re.compile(r'^protocol size sockets memory press maxhdr slab module cl co di ac io in de sh ss gs se re sp bi br ha uh gp em\n')
net_route_p = re.compile(r'^Iface\tDestination\tGateway \tFlags\tRefCnt\tUse\tMetric\tMask\t\tMTU\tWindow\tIRTT\s+\n') net_route_p = re.compile(r'^Iface\tDestination\tGateway \tFlags\tRefCnt\tUse\tMetric\tMask\t\tMTU\tWindow\tIRTT\s+\n')
net_tcp_p = re.compile(r'^\s+sl\s+local_address\s+(?:rem_address|remote_address)\s+st\s+tx_queue\s+rx_queue\s+tr\s+tm->when\s+retrnsmt\s+uid\s+timeout\s+inode')
net_unix_p = re.compile(r'^Num RefCount Protocol Flags Type St Inode Path\n') net_unix_p = re.compile(r'^Num RefCount Protocol Flags Type St Inode Path\n')
pid_fdinfo_p = re.compile(r'^pos:\t\d+\nflags:\t\d+\nmnt_id:\t\d+\n') pid_fdinfo_p = re.compile(r'^pos:\t\d+\nflags:\t\d+\nmnt_id:\t\d+\n')
@ -249,6 +250,7 @@ def parse(
net_packet_p: 'proc_net_packet', net_packet_p: 'proc_net_packet',
net_protocols_p: 'proc_net_protocols', net_protocols_p: 'proc_net_protocols',
net_route_p: 'proc_net_route', net_route_p: 'proc_net_route',
net_tcp_p: 'proc_net_tcp',
net_unix_p: 'proc_net_unix', net_unix_p: 'proc_net_unix',
net_ipv6_route_p: 'proc_net_ipv6_route', # before net_dev_mcast net_ipv6_route_p: 'proc_net_ipv6_route', # before net_dev_mcast
net_dev_mcast_p: 'proc_net_dev_mcast', # after net_ipv6_route net_dev_mcast_p: 'proc_net_dev_mcast', # after net_ipv6_route

293
jc/parsers/proc_net_tcp.py Normal file
View File

@ -0,0 +1,293 @@
"""jc - JSON Convert `/proc/net/tcp` and `proc/net/tcp6` file parser
IPv4 and IPv6 addresses are converted to standard notation unless the raw
(--raw) option is used.
Usage (cli):
$ cat /proc/net/tcp | jc --proc
or
$ jc /proc/net/tcp
or
$ cat /proc/net/tcp | jc --proc-net-tcp
Usage (module):
import jc
result = jc.parse('proc', proc_net_tcp_file)
or
import jc
result = jc.parse('proc_net_tcp', proc_net_tcp_file)
Schema:
Field names and types gathered from the following:
https://www.kernel.org/doc/Documentation/networking/proc_net_tcp.txt
https://github.com/torvalds/linux/blob/master/net/ipv4/tcp_ipv4.c
https://github.com/torvalds/linux/blob/master/net/ipv6/tcp_ipv6.c
[
{
"entry": integer,
"local_address": string,
"local_port": integer,
"remote_address": string,
"remote_port": integer,
"state": string,
"tx_queue": string,
"rx_queue": string,
"timer_active": integer,
"jiffies_until_timer_expires": string,
"unrecovered_rto_timeouts": string,
"uid": integer,
"unanswered_0_window_probes": integer,
"inode": integer,
"sock_ref_count": integer,
"sock_mem_loc": string,
"retransmit_timeout": integer,
"soft_clock_tick": integer,
"ack_quick_pingpong": integer,
"sending_congestion_window": integer,
"slow_start_size_threshold": integer
}
]
Examples:
$ cat /proc/net/tcp | jc --proc -p
[
{
"entry": "0",
"local_address": "10.0.0.28",
"local_port": 42082,
"remote_address": "64.12.0.108",
"remote_port": 80,
"state": "04",
"tx_queue": "00000001",
"rx_queue": "00000000",
"timer_active": 1,
"jiffies_until_timer_expires": "00000015",
"unrecovered_rto_timeouts": "00000000",
"uid": 0,
"unanswered_0_window_probes": 0,
"inode": 0,
"sock_ref_count": 3,
"sock_mem_loc": "ffff8c7a0de930c0",
"retransmit_timeout": 21,
"soft_clock_tick": 4,
"ack_quick_pingpong": 30,
"sending_congestion_window": 10,
"slow_start_size_threshold": -1
},
{
"entry": "1",
"local_address": "10.0.0.28",
"local_port": 38864,
"remote_address": "104.244.42.65",
"remote_port": 80,
"state": "06",
"tx_queue": "00000000",
"rx_queue": "00000000",
"timer_active": 3,
"jiffies_until_timer_expires": "000007C5",
"unrecovered_rto_timeouts": "00000000",
"uid": 0,
"unanswered_0_window_probes": 0,
"inode": 0,
"sock_ref_count": 3,
"sock_mem_loc": "ffff8c7a12d31aa0"
},
...
]
$ cat /proc/net/tcp | jc --proc -p -r
[
{
"entry": "1",
"local_address": "1C00000A",
"local_port": "A462",
"remote_address": "6C000C40",
"remote_port": "0050",
"state": "04",
"tx_queue": "00000001",
"rx_queue": "00000000",
"timer_active": "01",
"jiffies_until_timer_expires": "00000015",
"unrecovered_rto_timeouts": "00000000",
"uid": "0",
"unanswered_0_window_probes": "0",
"inode": "0",
"sock_ref_count": "3",
"sock_mem_loc": "ffff8c7a0de930c0",
"retransmit_timeout": "21",
"soft_clock_tick": "4",
"ack_quick_pingpong": "30",
"sending_congestion_window": "10",
"slow_start_size_threshold": "-1"
},
{
"entry": "2",
"local_address": "1C00000A",
"local_port": "97D0",
"remote_address": "412AF468",
"remote_port": "0050",
"state": "06",
"tx_queue": "00000000",
"rx_queue": "00000000",
"timer_active": "03",
"jiffies_until_timer_expires": "000007C5",
"unrecovered_rto_timeouts": "00000000",
"uid": "0",
"unanswered_0_window_probes": "0",
"inode": "0",
"sock_ref_count": "3",
"sock_mem_loc": "ffff8c7a12d31aa0"
},
...
]
"""
import binascii
import socket
import struct
from typing import List, Dict
import jc.utils
class info():
"""Provides parser metadata (version, author, etc.)"""
version = '1.0'
description = '`/proc/net/tcp` and `/proc/net/tcp6` file parser'
author = 'Alvin Solomon'
author_email = 'alvinms01@gmail.com'
compatible = ['linux']
tags = ['file']
hidden = True
__version__ = info.version
def hex_to_ip(hexaddr: str) -> str:
if len(hexaddr) == 8:
addr_long = int(hexaddr, 16)
return socket.inet_ntop(socket.AF_INET, struct.pack("<L", addr_long))
elif len(hexaddr) == 32:
addr = binascii.a2b_hex(hexaddr)
addr_tup = struct.unpack('>IIII', addr)
addr_bytes = struct.pack('@IIII', *addr_tup)
return socket.inet_ntop(socket.AF_INET6, addr_bytes)
return ''
def _process(proc_data: List[Dict]) -> List[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.
"""
int_list = {
'timer_active', 'uid', 'unanswered_0_window_probes', 'inode',
'sock_ref_count', 'retransmit_timeout', 'soft_clock_tick',
'ack_quick_pingpong', 'sending_congestion_window',
'slow_start_size_threshold'
}
for entry in proc_data:
if 'local_address' in entry:
entry['local_address'] = hex_to_ip(entry['local_address'])
entry['local_port'] = int(entry['local_port'], 16)
entry['remote_address'] = hex_to_ip(entry['remote_address'])
entry['remote_port'] = int(entry['remote_port'], 16)
for item in int_list:
if item in entry:
entry[item] = jc.utils.convert_to_int(entry[item])
return proc_data
def parse(
data: str,
raw: bool = False,
quiet: bool = False
) -> List[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:
List of Dictionaries. Raw or processed structured data.
"""
jc.utils.compatibility(__name__, info.compatible, quiet)
jc.utils.input_type_check(data)
raw_output: List = []
if jc.utils.has_data(data):
line_data = data.splitlines()[1:]
for entry in line_data:
line = entry.split()
output_line = {}
output_line['entry'] = line[0][:-1]
local_ip_port = line[1]
local_ip = local_ip_port.split(':')[0]
local_port = local_ip_port.split(':')[1]
output_line['local_address'] = local_ip
output_line['local_port'] = local_port
remote_ip_port = line[2]
remote_ip = remote_ip_port.split(':')[0]
remote_port = remote_ip_port.split(':')[1]
output_line['remote_address'] = remote_ip
output_line['remote_port'] = remote_port
output_line['state'] = line[3]
output_line['tx_queue'] = line[4][:8]
output_line['rx_queue'] = line[4][9:]
output_line['timer_active'] = line[5][:2]
output_line['jiffies_until_timer_expires'] = line[5][3:]
output_line['unrecovered_rto_timeouts'] = line[6]
output_line['uid'] = line[7]
output_line['unanswered_0_window_probes'] = line[8]
output_line['inode'] = line[9]
output_line['sock_ref_count'] = line[10]
output_line['sock_mem_loc'] = line[11]
# fields not always included
if len(line) > 12:
output_line['retransmit_timeout'] = line[12]
output_line['soft_clock_tick'] = line[13]
output_line['ack_quick_pingpong'] = line[14]
output_line['sending_congestion_window'] = line[15]
output_line['slow_start_size_threshold'] = line[16]
raw_output.append(output_line)
return raw_output if raw else _process(raw_output)

171
jc/parsers/resolve_conf.py Normal file
View File

@ -0,0 +1,171 @@
"""jc - JSON Convert `/etc/resolve.conf` file parser
This parser may be more forgiving than the system parser. For example, if
multiple `search` lists are defined, this parser will append all entries to
the `search` field, while the system parser may only use the list from the
last defined instance.
Usage (cli):
$ cat /etc/resolve.conf | jc --resolve-conf
Usage (module):
import jc
result = jc.parse('resolve_conf', resolve_conf_output)
Schema:
{
"domain": string,
"search": [
string
],
"nameservers": [
string
],
"options": [
string
],
"sortlist": [
string
]
}
Examples:
$ cat /etc/resolve.conf | jc --resolve-conf -p
{
"search": [
"eng.myprime.com",
"dev.eng.myprime.com",
"labs.myprime.com",
"qa.myprime.com"
],
"nameservers": [
"10.136.17.15"
],
"options": [
"rotate",
"ndots:1"
]
}
"""
import re
from typing import List, Dict
from jc.jc_types import JSONDictType
import jc.utils
class info():
"""Provides parser metadata (version, author, etc.)"""
version = '1.0'
description = '`/etc/resolve.conf` file parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
compatible = ['linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd']
tags = ['file']
__version__ = info.version
def _process(proc_data: JSONDictType) -> JSONDictType:
"""
Final processing to conform to the schema.
Parameters:
proc_data: Dictionary raw structured data to process
Returns:
Dictionary. Structured to conform to the schema.
"""
return proc_data
def parse(
data: str,
raw: bool = False,
quiet: bool = False
) -> JSONDictType:
"""
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 = {}
search: List[str] = []
nameservers: List[str] = []
options: List[str] = []
sortlist: List[str] = []
if jc.utils.has_data(data):
for line in filter(None, data.splitlines()):
# comments start with # or ; and can be inline
if '#' in line or ';' in line:
userdata = list(filter(None, re.split("[#;]+", line, maxsplit=1)))
userdata = [x for x in userdata if x.strip()]
if len(userdata) <= 1: # whole line is a comment
continue
userdata_str = userdata[0].strip()
else:
userdata_str = line.strip()
if userdata_str.startswith('domain'):
raw_output['domain'] = userdata_str.split()[1].strip()
continue
if userdata_str.startswith('search'):
search_items = userdata_str.split(maxsplit=1)[1]
search_list = search_items.split()
search.extend(search_list)
continue
if userdata_str.startswith('nameserver'):
ns_str = userdata_str.split()[1]
nameservers.append(ns_str)
continue
if userdata_str.startswith('options'):
option_items = userdata_str.split(maxsplit=1)[1]
option_list = option_items.split()
options.extend(option_list)
continue
if userdata_str.startswith('sortlist'):
sortlist_items = userdata_str.split(maxsplit=1)[1]
sortlist_list = sortlist_items.split()
sortlist.extend(sortlist_list)
continue
if search:
raw_output['search'] = search
if nameservers:
raw_output['nameservers'] = nameservers
if options:
raw_output['options'] = options
if sortlist:
raw_output['sortlist'] = sortlist
return raw_output if raw else _process(raw_output)

View File

@ -1,4 +1,4 @@
.TH jc 1 2023-06-21 1.23.3 "JSON Convert" .TH jc 1 2023-07-30 1.23.4 "JSON Convert"
.SH NAME .SH NAME
\fBjc\fP \- JSON Convert JSONifies the output of many CLI tools, file-types, \fBjc\fP \- JSON Convert JSONifies the output of many CLI tools, file-types,
and strings and strings
@ -192,6 +192,11 @@ Email Address string parser
\fB--file\fP \fB--file\fP
`file` command parser `file` command parser
.TP
.B
\fB--find\fP
`find` command parser
.TP .TP
.B .B
\fB--findmnt\fP \fB--findmnt\fP
@ -307,6 +312,11 @@ IPv4 and IPv6 Address string parser
\fB--iptables\fP \fB--iptables\fP
`iptables` command parser `iptables` command parser
.TP
.B
\fB--ip-route\fP
`ip route` command parser
.TP .TP
.B .B
\fB--iso-datetime\fP \fB--iso-datetime\fP
@ -692,6 +702,11 @@ PLIST file parser
\fB--proc-net-route\fP \fB--proc-net-route\fP
`/proc/net/route` file parser `/proc/net/route` file parser
.TP
.B
\fB--proc-net-tcp\fP
`/proc/net/tcp` and `/proc/net/tcp6` file parser
.TP .TP
.B .B
\fB--proc-net-unix\fP \fB--proc-net-unix\fP
@ -747,6 +762,11 @@ PLIST file parser
\fB--ps\fP \fB--ps\fP
`ps` command parser `ps` command parser
.TP
.B
\fB--resolve-conf\fP
`/etc/resolve.conf` file parser
.TP .TP
.B .B
\fB--route\fP \fB--route\fP

View File

@ -5,7 +5,7 @@ with open('README.md', 'r') as f:
setuptools.setup( setuptools.setup(
name='jc', name='jc',
version='1.23.3', version='1.23.4',
author='Kelly Brazil', author='Kelly Brazil',
author_email='kellyjonbrazil@gmail.com', author_email='kellyjonbrazil@gmail.com',
description='Converts the output of popular command-line tools and file-types to JSON.', description='Converts the output of popular command-line tools and file-types to JSON.',

13
tests/fixtures/centos-7.7/find.json vendored Normal file
View File

@ -0,0 +1,13 @@
[{"path": null, "node": "."},
{"path":".","node":null},
{"path": ".","node": "jc"},
{"path": "./jc","node": "tests"},
{"path": "./jc/tests","node": "test_find.py"},
{"path": "./jc/tests","node": "test_history.py"},
{"path": "./jc/tests","node": "test_hosts.py"},
{"path": "./jc","node": "anotherdirectory"},
{"path": null,"node": null,"error": "find: './inaccessible': Permission denied"},
{"path": "./jc","node": "directory2"},
{"path": "./jc/directory2","node": "file.txt"},
{"path": "./jc/directory2","node": "file2.txt"},
{"path": ".","node": "newfile.txt"}]

13
tests/fixtures/centos-7.7/find.out vendored Normal file
View File

@ -0,0 +1,13 @@
.
./
./jc
./jc/tests
./jc/tests/test_find.py
./jc/tests/test_history.py
./jc/tests/test_hosts.py
./jc/anotherdirectory
find: './inaccessible': Permission denied
./jc/directory2
./jc/directory2/file.txt
./jc/directory2/file2.txt
./newfile.txt

31
tests/fixtures/centos-7.7/ip_route.json vendored Normal file
View File

@ -0,0 +1,31 @@
[
{
"ip": "default",
"via": "10.0.2.2",
"dev": "enp0s3",
"proto": "dhcp",
"metric": 100
},
{
"ip": "10.0.2.0/24",
"dev": "enp0s3",
"proto": "kernel",
"scope": "link",
"src": "10.0.2.15",
"metric": 100
},
{
"ip": "169.254.0.0/16",
"dev": "enp0s3",
"scope": "link",
"metric": 1000
},
{
"ip": "172.17.0.0/16",
"dev": "docker0",
"proto": "kernel",
"scope": "link",
"src": "172.17.0.1",
"status": "linkdown"
}
]

View File

@ -0,0 +1,4 @@
default via 10.0.2.2 dev enp0s3 proto dhcp metric 100
10.0.2.0/24 dev enp0s3 proto kernel scope link src 10.0.2.15 metric 100
169.254.0.0/16 dev enp0s3 scope link metric 1000
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown

12
tests/fixtures/generic/resolve.conf-1 vendored Normal file
View File

@ -0,0 +1,12 @@
# Generated by NetworkManager
search hsd1.ca.comcast.net
nameserver 75.75.75.75 ; test inline comment
nameserver 75.75.76.76 # test inline comment
nameserver 2001:558:feed::1
# NOTE: the libc resolver may not support more than 3 nameservers.
# The nameservers listed below may not be recognized.
nameserver 2001:558:feed::2
sortlist 130.155.160.0/255.255.240.0 130.155.0.0
search hello.com world.com # add another search list for fun

View File

@ -0,0 +1 @@
{"search":["hsd1.ca.comcast.net","hello.com","world.com"],"nameservers":["75.75.75.75","75.75.76.76","2001:558:feed::1","2001:558:feed::2"],"sortlist":["130.155.160.0/255.255.240.0","130.155.0.0"]}

4
tests/fixtures/generic/resolve.conf-2 vendored Normal file
View File

@ -0,0 +1,4 @@
search eng.myprime.com dev.eng.myprime.com labs.myprime.com qa.myprime.com
options rotate
options ndots:1
nameserver 10.136.17.15

View File

@ -0,0 +1 @@
{"search":["eng.myprime.com","dev.eng.myprime.com","labs.myprime.com","qa.myprime.com"],"nameservers":["10.136.17.15"],"options":["rotate","ndots:1"]}

7
tests/fixtures/generic/resolve.conf-3 vendored Normal file
View File

@ -0,0 +1,7 @@
;
; /etc/resolv.conf file for dnsmaster (sirius)
;
domain doc.com
nameserver 0.0.0.0
nameserver 111.22.3.5

View File

@ -0,0 +1 @@
{"domain":"doc.com","nameservers":["0.0.0.0","111.22.3.5"]}

5
tests/fixtures/generic/resolve.conf-4 vendored Normal file
View File

@ -0,0 +1,5 @@
; generated by /sbin/dhclient-script
search example.com
options rotate timeout:1 retries:1
nameserver 10.1.1.2
nameserver 10.1.1.1

View File

@ -0,0 +1 @@
{"search":["example.com"],"nameservers":["10.1.1.2","10.1.1.1"],"options":["rotate","timeout:1","retries:1"]}

28
tests/fixtures/linux-proc/net_tcp vendored Normal file
View File

@ -0,0 +1,28 @@
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
0: 3500007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 101 0 34000 1 0000000000000000 100 0 0 10 5
1: 0100007F:89E7 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 140054 1 0000000000000000 100 0 0 10 0
2: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 34523 1 0000000000000000 100 0 0 10 0
3: 802AA8C0:D450 2104C798:01BB 08 00000000:00000052 02:00000A6F 00000000 1000 0 149098 2 0000000000000000 20 4 0 10 -1
0: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23459 1 ffff8c7a0de93a80 100 0 0 10 0
1: 1C00000A:A462 6C000C40:0050 04 00000001:00000000 01:00000015 00000000 0 0 0 3 ffff8c7a0de930c0 21 4 30 10 -1
2: 1C00000A:97D0 412AF468:0050 06 00000000:00000000 03:000007C5 00000000 0 0 0 3 ffff8c7a12d31aa0
3: 1C00000A:B082 E4BDFA8E:0050 06 00000000:00000000 03:00000799 00000000 0 0 0 3 ffff8c7a12d31990
4: 1C00000A:A858 A6644468:0050 06 00000000:00000000 03:000007C4 00000000 0 0 0 3 ffff8c7a12d31000
5: 1C00000A:BD06 2316F09D:0050 06 00000000:00000000 03:000007C4 00000000 0 0 0 3 ffff8c7a12d31880
6: 1C00000A:9572 69769736:0050 04 00000001:00000000 01:00000015 00000000 0 0 0 3 ffff8c7a0de94e00 21 4 30 10 -1
7: 1C00000A:A530 DA436C68:0050 04 00000001:00000000 01:00000016 00000000 0 0 0 3 ffff8c7a0de91380 22 4 30 10 -1
8: 1C00000A:8DDC 9F426597:0050 06 00000000:00000000 03:000007B5 00000000 0 0 0 3 ffff8c7a12d31110
9: 1C00000A:C7DE A9664468:0050 04 00000001:00000000 01:00000015 00000000 0 0 0 3 ffff8c7a0de96b40 21 4 18 10 -1
10: 1C00000A:DF22 412AF468:0050 06 00000000:00000000 03:00001747 00000000 0 0 0 3 ffff8c7a12d31cc0
11: 1C00000A:0016 9200000A:DDCB 01 00000000:00000000 02:000AB71D 00000000 0 0 41558 2 ffff8c7a0de957c0 20 4 1 10 -1
12: 1C00000A:DFF8 A40B8962:0050 06 00000000:00000000 03:00001722 00000000 0 0 0 3 ffff8c7a12d31660
13: 1C00000A:A5BE A6644468:0050 06 00000000:00000000 03:00001768 00000000 0 0 0 3 ffff8c7a12d31770
14: 1C00000A:DA30 9F426597:0050 06 00000000:00000000 03:00001731 00000000 0 0 0 3 ffff8c7a12d31dd0
15: 1C00000A:9F62 192E3E17:0050 04 00000001:00000000 01:00000015 00000000 0 0 0 3 ffff8c7a0de909c0 21 4 30 10 -1
16: 1C00000A:DA50 E4BDFA8E:0050 06 00000000:00000000 03:00001716 00000000 0 0 0 3 ffff8c7a12d31ee0
17: 1C00000A:C362 2316F09D:0050 06 00000000:00000000 03:00001748 00000000 0 0 0 3 ffff8c7a12d31330
18: 1C00000A:A734 15E7064A:0050 06 00000000:00000000 03:000007A7 00000000 0 0 0 3 ffff8c7a12d31440
19: 1C00000A:EA10 A9664468:0050 06 00000000:00000000 03:000007C4 00000000 0 0 0 3 ffff8c7a12d31550
20: 1C00000A:D7C6 B0D4B136:0050 06 00000000:00000000 03:000007C4 00000000 0 0 0 3 ffff8c7a12d31bb0
21: 1C00000A:DD12 DA436C68:0050 06 00000000:00000000 03:000007C4 00000000 0 0 0 3 ffff8c7a12d31220
22: 1C00000A:D514 8000C798:0050 04 00000001:00000000 01:00000015 00000000 0 0 0 3 ffff8c7a0de94440 21 4 30 10 -1

File diff suppressed because one or more lines are too long

9
tests/fixtures/linux-proc/net_tcp6 vendored Normal file
View File

@ -0,0 +1,9 @@
sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
0: 00000000000000000000000000000000:0016 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23556 1 ffff8c7a0dee0000 100 0 0 10 0
1: 4606012600F1019E000000004C3A0000:E700 8028032A830031F10CB0CEFADE250000:0050 06 00000000:00000000 03:000003D1 00000000 0 0 0 3 ffff8c7a1c76d000
2: 4606012600F1019E000000004C3A0000:E9E6 98490120073544000000000000800000:0050 06 00000000:00000000 03:000003AD 00000000 0 0 0 3 ffff8c7a1c76d440
3: 4606012600F1019E000000004C3A0000:95E2 061400268F01003A000000003A0C0000:0050 06 00000000:00000000 03:00000400 00000000 0 0 0 3 ffff8c7a1c76daa0
4: 4606012600F1019E000000004C3A0000:AFE4 59050120916019000000000020070000:0050 06 00000000:00000000 03:000003EC 00000000 0 0 0 3 ffff8c7a1c76d550
5: 4606012600F1019E000000004C3A0000:9D18 B0F80726010805400000000004200000:0050 06 00000000:00000000 03:00000396 00000000 0 0 0 3 ffff8c7a1c76dcc0
6: 4606012600F1019E000000004C3A0000:EE0A 590501208F60190000000000330B0000:0050 06 00000000:00000000 03:000003FC 00000000 0 0 0 3 ffff8c7a1c76d110
7: 4606012600F1019E000000004C3A0000:80A8 5905012000C01900000000001333C517:0050 06 00000000:00000000 03:000003FC 00000000 0 0 0 3 ffff8c7a1c76d330

View File

@ -0,0 +1 @@
[{"entry":"0","local_address":"::","local_port":22,"remote_address":"::","remote_port":0,"state":"0A","tx_queue":"00000000","rx_queue":"00000000","timer_active":0,"jiffies_until_timer_expires":"00000000","unrecovered_rto_timeouts":"00000000","uid":0,"unanswered_0_window_probes":0,"inode":23556,"sock_ref_count":1,"sock_mem_loc":"ffff8c7a0dee0000","retransmit_timeout":100,"soft_clock_tick":0,"ack_quick_pingpong":0,"sending_congestion_window":10,"slow_start_size_threshold":0},{"entry":"1","local_address":"2601:646:9e01:f100::3a4c","local_port":59136,"remote_address":"2a03:2880:f131:83:face:b00c:0:25de","remote_port":80,"state":"06","tx_queue":"00000000","rx_queue":"00000000","timer_active":3,"jiffies_until_timer_expires":"000003D1","unrecovered_rto_timeouts":"00000000","uid":0,"unanswered_0_window_probes":0,"inode":0,"sock_ref_count":3,"sock_mem_loc":"ffff8c7a1c76d000"},{"entry":"2","local_address":"2601:646:9e01:f100::3a4c","local_port":59878,"remote_address":"2001:4998:44:3507::8000","remote_port":80,"state":"06","tx_queue":"00000000","rx_queue":"00000000","timer_active":3,"jiffies_until_timer_expires":"000003AD","unrecovered_rto_timeouts":"00000000","uid":0,"unanswered_0_window_probes":0,"inode":0,"sock_ref_count":3,"sock_mem_loc":"ffff8c7a1c76d440"},{"entry":"3","local_address":"2601:646:9e01:f100::3a4c","local_port":38370,"remote_address":"2600:1406:3a00:18f::c3a","remote_port":80,"state":"06","tx_queue":"00000000","rx_queue":"00000000","timer_active":3,"jiffies_until_timer_expires":"00000400","unrecovered_rto_timeouts":"00000000","uid":0,"unanswered_0_window_probes":0,"inode":0,"sock_ref_count":3,"sock_mem_loc":"ffff8c7a1c76daa0"},{"entry":"4","local_address":"2601:646:9e01:f100::3a4c","local_port":45028,"remote_address":"2001:559:19:6091::720","remote_port":80,"state":"06","tx_queue":"00000000","rx_queue":"00000000","timer_active":3,"jiffies_until_timer_expires":"000003EC","unrecovered_rto_timeouts":"00000000","uid":0,"unanswered_0_window_probes":0,"inode":0,"sock_ref_count":3,"sock_mem_loc":"ffff8c7a1c76d550"},{"entry":"5","local_address":"2601:646:9e01:f100::3a4c","local_port":40216,"remote_address":"2607:f8b0:4005:801::2004","remote_port":80,"state":"06","tx_queue":"00000000","rx_queue":"00000000","timer_active":3,"jiffies_until_timer_expires":"00000396","unrecovered_rto_timeouts":"00000000","uid":0,"unanswered_0_window_probes":0,"inode":0,"sock_ref_count":3,"sock_mem_loc":"ffff8c7a1c76dcc0"},{"entry":"6","local_address":"2601:646:9e01:f100::3a4c","local_port":60938,"remote_address":"2001:559:19:608f::b33","remote_port":80,"state":"06","tx_queue":"00000000","rx_queue":"00000000","timer_active":3,"jiffies_until_timer_expires":"000003FC","unrecovered_rto_timeouts":"00000000","uid":0,"unanswered_0_window_probes":0,"inode":0,"sock_ref_count":3,"sock_mem_loc":"ffff8c7a1c76d110"},{"entry":"7","local_address":"2601:646:9e01:f100::3a4c","local_port":32936,"remote_address":"2001:559:19:c000::17c5:3313","remote_port":80,"state":"06","tx_queue":"00000000","rx_queue":"00000000","timer_active":3,"jiffies_until_timer_expires":"000003FC","unrecovered_rto_timeouts":"00000000","uid":0,"unanswered_0_window_probes":0,"inode":0,"sock_ref_count":3,"sock_mem_loc":"ffff8c7a1c76d330"}]

13
tests/fixtures/ubuntu-18.04/find.json vendored Normal file
View File

@ -0,0 +1,13 @@
[{"path": null, "node": "."},
{"path":".","node":null},
{"path": ".","node": "jc"},
{"path": "./jc","node": "tests"},
{"path": "./jc/tests","node": "test_find.py"},
{"path": "./jc/tests","node": "test_history.py"},
{"path": "./jc/tests","node": "test_hosts.py"},
{"path": "./jc","node": "anotherdirectory"},
{"path": null,"node": null,"error": "find: './inaccessible': Permission denied"},
{"path": "./jc","node": "directory2"},
{"path": "./jc/directory2","node": "file.txt"},
{"path": "./jc/directory2","node": "file2.txt"},
{"path": ".","node": "newfile.txt"}]

13
tests/fixtures/ubuntu-18.04/find.out vendored Normal file
View File

@ -0,0 +1,13 @@
.
./
./jc
./jc/tests
./jc/tests/test_find.py
./jc/tests/test_history.py
./jc/tests/test_hosts.py
./jc/anotherdirectory
find: './inaccessible': Permission denied
./jc/directory2
./jc/directory2/file.txt
./jc/directory2/file2.txt
./newfile.txt

View File

@ -0,0 +1,31 @@
[
{
"ip": "default",
"via": "10.0.2.2",
"dev": "enp0s3",
"proto": "dhcp",
"metric": 100
},
{
"ip": "10.0.2.0/24",
"dev": "enp0s3",
"proto": "kernel",
"scope": "link",
"src": "10.0.2.15",
"metric": 100
},
{
"ip": "169.254.0.0/16",
"dev": "enp0s3",
"scope": "link",
"metric": 1000
},
{
"ip": "172.17.0.0/16",
"dev": "docker0",
"proto": "kernel",
"scope": "link",
"src": "172.17.0.1",
"status": "linkdown"
}
]

View File

@ -0,0 +1,4 @@
default via 10.0.2.2 dev enp0s3 proto dhcp metric 100
10.0.2.0/24 dev enp0s3 proto kernel scope link src 10.0.2.15 metric 100
169.254.0.0/16 dev enp0s3 scope link metric 1000
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown

43
tests/test_find.py Normal file
View File

@ -0,0 +1,43 @@
import os
import unittest
import json
import jc.parsers.find
THIS_DIR = os.path.dirname(os.path.abspath(__file__))
class MyTests(unittest.TestCase):
# input
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/find.out'), 'r', encoding='utf-8') as f:
centos_7_7_find = f.read()
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/find.out'), 'r', encoding='utf-8') as f:
ubuntu_18_4_find = f.read()
#output
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/find.json'), 'r', encoding='utf-8') as f:
centos_7_7_find_json = json.loads(f.read())
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/find.json'), 'r', encoding='utf-8') as f:
ubuntu_18_4_find_json = json.loads(f.read())
def test_find_nodata(self):
"""
Test 'find' with no data
"""
self.assertEqual(jc.parsers.find.parse('', quiet=True), [])
def test_find_centos_7_7(self):
"""
Test 'find' on Centos 7.7
"""
self.assertEqual(jc.parsers.find.parse(self.centos_7_7_find, quiet=True), self.centos_7_7_find_json)
def test_find_ubuntu_18_4(self):
"""
Test 'find' on Ubuntu 18.4
"""
self.assertEqual(jc.parsers.find.parse(self.ubuntu_18_4_find, quiet=True), self.ubuntu_18_4_find_json)
if __name__ == '__main__':
unittest.main()

51
tests/test_ip_route.py Normal file
View File

@ -0,0 +1,51 @@
import os
import json
import unittest
import jc.parsers.ip_route
THIS_DIR = os.path.dirname(os.path.abspath(__file__))
class MyTests(unittest.TestCase):
# INPUT
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/ip_route.out'), 'r',
encoding='utf-8') as f:
ubuntu_18_4_ip_route = f.read()
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/ip_route.out'), 'r',
encoding='utf-8') as f:
centos_7_7_ip_route = f.read()
# OUTPUT
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/ip_route.json'), 'r',
encoding='utf-8') as f:
ubuntu_18_4_ip_route_json = json.loads(f.read())
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/ip_route.json'), 'r',
encoding='utf-8') as f:
centos_7_7_ip_route_json = json.loads(f.read())
def test_ip_route_nodata(self):
"""
Test 'ip_route' with no data
"""
self.assertEqual(jc.parsers.ip_route.parse('', quiet=True), [])
def test_ip_route_ubuntu_18_4(self):
"""
Test 'ip_route' on Ubuntu 18.4
"""
self.assertEqual(jc.parsers.ip_route.parse(self.ubuntu_18_4_ip_route, quiet=True),
self.ubuntu_18_4_ip_route_json)
def test_ip_route_centos_7_7(self):
"""
Test 'history' on Centos 7.7
"""
self.assertEqual(jc.parsers.ip_route.parse(self.centos_7_7_ip_route, quiet=True),
self.centos_7_7_ip_route_json)
if __name__ == '__main__':
unittest.main()

View File

@ -0,0 +1,53 @@
import os
import unittest
import json
from typing import Dict
import jc.parsers.proc_net_tcp
THIS_DIR = os.path.dirname(os.path.abspath(__file__))
class MyTests(unittest.TestCase):
f_in: Dict = {}
f_json: Dict = {}
@classmethod
def setUpClass(cls):
fixtures = {
'proc_net_tcp': (
'fixtures/linux-proc/net_tcp',
'fixtures/linux-proc/net_tcp.json'),
'proc_net_tcp6': (
'fixtures/linux-proc/net_tcp6',
'fixtures/linux-proc/net_tcp6.json')
}
for file, filepaths in fixtures.items():
with open(os.path.join(THIS_DIR, filepaths[0]), 'r', encoding='utf-8') as a, \
open(os.path.join(THIS_DIR, filepaths[1]), 'r', encoding='utf-8') as b:
cls.f_in[file] = a.read()
cls.f_json[file] = json.loads(b.read())
def test_proc_net_tcp_nodata(self):
"""
Test 'proc_net_tcp' with no data
"""
self.assertEqual(jc.parsers.proc_net_tcp.parse('', quiet=True), [])
def test_proc_net_tcp(self):
"""
Test '/proc/net/tcp'
"""
self.assertEqual(jc.parsers.proc_net_tcp.parse(self.f_in['proc_net_tcp'], quiet=True),
self.f_json['proc_net_tcp'])
def test_proc_net_tcp6(self):
"""
Test '/proc/net/tcp6'
"""
self.assertEqual(jc.parsers.proc_net_tcp.parse(self.f_in['proc_net_tcp6'], quiet=True),
self.f_json['proc_net_tcp6'])
if __name__ == '__main__':
unittest.main()

View File

@ -0,0 +1,83 @@
import os
import unittest
import json
from typing import Dict
from jc.parsers.resolve_conf import parse
THIS_DIR = os.path.dirname(os.path.abspath(__file__))
class MyTests(unittest.TestCase):
f_in: Dict = {}
f_json: Dict = {}
@classmethod
def setUpClass(cls):
fixtures = {
'resolve_conf_1': (
'fixtures/generic/resolve.conf-1',
'fixtures/generic/resolve.conf-1.json'),
'resolve_conf_2': (
'fixtures/generic/resolve.conf-2',
'fixtures/generic/resolve.conf-2.json'),
'resolve_conf_3': (
'fixtures/generic/resolve.conf-3',
'fixtures/generic/resolve.conf-3.json'),
'resolve_conf_4': (
'fixtures/generic/resolve.conf-4',
'fixtures/generic/resolve.conf-4.json')
}
for file, filepaths in fixtures.items():
with open(os.path.join(THIS_DIR, filepaths[0]), 'r', encoding='utf-8') as a, \
open(os.path.join(THIS_DIR, filepaths[1]), 'r', encoding='utf-8') as b:
cls.f_in[file] = a.read()
cls.f_json[file] = json.loads(b.read())
def test_resolve_conf_nodata(self):
"""
Test 'resolve_conf' with no data
"""
self.assertEqual(parse('', quiet=True), {})
def test_resolve_conf_1(self):
"""
Test 'resolve_conf' file 1
"""
self.assertEqual(
parse(self.f_in['resolve_conf_1'], quiet=True),
self.f_json['resolve_conf_1']
)
def test_resolve_conf_2(self):
"""
Test 'resolve_conf' file 2
"""
self.assertEqual(
parse(self.f_in['resolve_conf_2'], quiet=True),
self.f_json['resolve_conf_2']
)
def test_resolve_conf_3(self):
"""
Test 'resolve_conf' file 3
"""
self.assertEqual(
parse(self.f_in['resolve_conf_3'], quiet=True),
self.f_json['resolve_conf_3']
)
def test_resolve_conf_4(self):
"""
Test 'resolve_conf' file 4
"""
self.assertEqual(
parse(self.f_in['resolve_conf_4'], quiet=True),
self.f_json['resolve_conf_4']
)
if __name__ == '__main__':
unittest.main()