diff --git a/.github/workflows/pythonapp.yml b/.github/workflows/pythonapp.yml index 319c64fe..75f17cfa 100644 --- a/.github/workflows/pythonapp.yml +++ b/.github/workflows/pythonapp.yml @@ -9,13 +9,41 @@ on: - "**/*.py" jobs: + very_old_python: + if: github.event.pull_request.draft == false + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [macos-13, windows-2019] + python-version: ["3.6"] + + steps: + - uses: actions/checkout@v3 + - name: "Set up timezone to America/Los_Angeles" + uses: szenius/set-timezone@v1.2 + with: + timezoneLinux: "America/Los_Angeles" + timezoneMacos: "America/Los_Angeles" + timezoneWindows: "Pacific Standard Time" + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + - name: Test with unittest + run: | + python -m unittest discover tests + old_python: if: github.event.pull_request.draft == false runs-on: ${{ matrix.os }} strategy: matrix: - os: [macos-13, ubuntu-20.04, windows-2019] - python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"] + os: [macos-13, ubuntu-22.04, windows-2019] + python-version: ["3.7", "3.8", "3.9", "3.10"] steps: - uses: actions/checkout@v3 diff --git a/CHANGELOG b/CHANGELOG index 0211ffaf..b81f641a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,17 @@ jc changelog +20250503 v1.25.5 +- Add `amixer` command parser +- Enhance `iptables` command parser to add default policy statistics fields +- Fix `bluetoothctl` parser failing to parse controllers with power state prop +- Fix `lsblk` command parser to support multiple mountpoints. Also, added + byte conversions for size fields. +- Fix `nmcli` command parser to support `team.config` JSON field +- Fix `time` command parser for output that does not contain centiseconds +- Fix `x509-cert` parser to handle IDNA2008 encoded email addresses with a warning +- Fix typing for upcoming python v3.14 +- Fix timezone setting for tests to support minimal chrooted builds + 20241125 v1.25.4 - Add `ipconfig` command parser (`ipconfig` for Windows) - Add `pacman` command parser diff --git a/README.md b/README.md index fa6933f5..adf49f5a 100644 --- a/README.md +++ b/README.md @@ -159,6 +159,7 @@ option. | `--acpi` | `acpi` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/acpi) | | `--airport` | `airport -I` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/airport) | | `--airport-s` | `airport -s` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/airport_s) | +| `--amixer` | `amixer` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/amixer) | | `--apt-cache-show` | `apt-cache show` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/apt_cache_show) | | `--apt-get-sqq` | `apt-get -sqq` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/apt_get_sqq) | | `--arp` | `arp` command parser | [details](https://kellyjonbrazil.github.io/jc/docs/parsers/arp) | @@ -1378,4 +1379,4 @@ cat istio.yaml | jc -p --yaml ] ``` -© 2019-2024 Kelly Brazil \ No newline at end of file +© 2019-2025 Kelly Brazil \ No newline at end of file diff --git a/completions/jc_bash_completion.sh b/completions/jc_bash_completion.sh index d122aa65..c032ed84 100644 --- a/completions/jc_bash_completion.sh +++ b/completions/jc_bash_completion.sh @@ -3,8 +3,8 @@ _jc() 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_commands=(acpi airport apt-cache apt-get arp blkid bluetoothctl cbt certbot chage cksum crontab curl date debconf-show df dig dmidecode dpkg du efibootmgr env ethtool file findmnt finger free git gpg hciconfig host id ifconfig iostat ip ipconfig iptables iw iwconfig jobs last lastb ls lsattr lsb_release lsblk lsmod lsof lspci lsusb md5 md5sum mdadm mount mpstat needrestart netstat nmcli nsd-control ntpq os-prober pacman pidstat ping ping6 pip pip3 postconf printenv ps route rpm rsync sfdisk sha1sum sha224sum sha256sum sha384sum sha512sum shasum ss ssh sshd stat sum swapon sysctl systemctl systeminfo timedatectl top tracepath tracepath6 traceroute traceroute6 tune2fs udevadm ufw uname update-alternatives upower uptime vdir veracrypt vmstat w wc wg who xrandr zipinfo zpool) - jc_parsers=(--acpi --airport --airport-s --apt-cache-show --apt-get-sqq --arp --asciitable --asciitable-m --blkid --bluetoothctl --cbt --cef --cef-s --certbot --chage --cksum --clf --clf-s --crontab --crontab-u --csv --csv-s --curl-head --date --datetime-iso --debconf-show --df --dig --dir --dmidecode --dpkg-l --du --efibootmgr --email-address --env --ethtool --file --find --findmnt --finger --free --fstab --git-log --git-log-s --git-ls-remote --gpg --group --gshadow --hash --hashsum --hciconfig --history --host --hosts --http-headers --id --ifconfig --ini --ini-dup --iostat --iostat-s --ip-address --ipconfig --iptables --ip-route --iw-scan --iwconfig --jar-manifest --jobs --jwt --kv --kv-dup --last --ls --ls-s --lsattr --lsb-release --lsblk --lsmod --lsof --lspci --lsusb --m3u --mdadm --mount --mpstat --mpstat-s --needrestart --netstat --nmcli --nsd-control --ntpq --openvpn --os-prober --os-release --pacman --passwd --path --path-list --pci-ids --pgpass --pidstat --pidstat-s --ping --ping-s --pip-list --pip-show --pkg-index-apk --pkg-index-deb --plist --postconf --proc --proc-buddyinfo --proc-cmdline --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 --swapon --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 --tune2fs --udevadm --ufw --ufw-appinfo --uname --update-alt-gs --update-alt-q --upower --uptime --url --ver --veracrypt --vmstat --vmstat-s --w --wc --wg-show --who --x509-cert --x509-csr --xml --xrandr --yaml --zipinfo --zpool-iostat --zpool-status) + jc_commands=(acpi airport amixer apt-cache apt-get arp blkid bluetoothctl cbt certbot chage cksum crontab curl date debconf-show df dig dmidecode dpkg du efibootmgr env ethtool file findmnt finger free git gpg hciconfig host id ifconfig iostat ip ipconfig iptables iw iwconfig jobs last lastb ls lsattr lsb_release lsblk lsmod lsof lspci lsusb md5 md5sum mdadm mount mpstat needrestart netstat nmcli nsd-control ntpq os-prober pacman pidstat ping ping6 pip pip3 postconf printenv ps route rpm rsync sfdisk sha1sum sha224sum sha256sum sha384sum sha512sum shasum ss ssh sshd stat sum swapon sysctl systemctl systeminfo timedatectl top tracepath tracepath6 traceroute traceroute6 tune2fs udevadm ufw uname update-alternatives upower uptime vdir veracrypt vmstat w wc wg who xrandr zipinfo zpool) + jc_parsers=(--acpi --airport --airport-s --amixer --apt-cache-show --apt-get-sqq --arp --asciitable --asciitable-m --blkid --bluetoothctl --cbt --cef --cef-s --certbot --chage --cksum --clf --clf-s --crontab --crontab-u --csv --csv-s --curl-head --date --datetime-iso --debconf-show --df --dig --dir --dmidecode --dpkg-l --du --efibootmgr --email-address --env --ethtool --file --find --findmnt --finger --free --fstab --git-log --git-log-s --git-ls-remote --gpg --group --gshadow --hash --hashsum --hciconfig --history --host --hosts --http-headers --id --ifconfig --ini --ini-dup --iostat --iostat-s --ip-address --ipconfig --iptables --ip-route --iw-scan --iwconfig --jar-manifest --jobs --jwt --kv --kv-dup --last --ls --ls-s --lsattr --lsb-release --lsblk --lsmod --lsof --lspci --lsusb --m3u --mdadm --mount --mpstat --mpstat-s --needrestart --netstat --nmcli --nsd-control --ntpq --openvpn --os-prober --os-release --pacman --passwd --path --path-list --pci-ids --pgpass --pidstat --pidstat-s --ping --ping-s --pip-list --pip-show --pkg-index-apk --pkg-index-deb --plist --postconf --proc --proc-buddyinfo --proc-cmdline --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 --swapon --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 --tune2fs --udevadm --ufw --ufw-appinfo --uname --update-alt-gs --update-alt-q --upower --uptime --url --ver --veracrypt --vmstat --vmstat-s --w --wc --wg-show --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 --slurp -s --unbuffer -u --yaml-out -y) jc_about_options=(--about -a) jc_about_mod_options=(--pretty -p --yaml-out -y --monochrome -m --force-color -C) diff --git a/completions/jc_zsh_completion.sh b/completions/jc_zsh_completion.sh index 4b7eb226..a8802b74 100644 --- a/completions/jc_zsh_completion.sh +++ b/completions/jc_zsh_completion.sh @@ -9,10 +9,11 @@ _jc() { jc_help_options jc_help_options_describe \ jc_special_options jc_special_options_describe - jc_commands=(acpi airport apt-cache apt-get arp blkid bluetoothctl cbt certbot chage cksum crontab curl date debconf-show df dig dmidecode dpkg du efibootmgr env ethtool file findmnt finger free git gpg hciconfig host id ifconfig iostat ip ipconfig iptables iw iwconfig jobs last lastb ls lsattr lsb_release lsblk lsmod lsof lspci lsusb md5 md5sum mdadm mount mpstat needrestart netstat nmcli nsd-control ntpq os-prober pacman pidstat ping ping6 pip pip3 postconf printenv ps route rpm rsync sfdisk sha1sum sha224sum sha256sum sha384sum sha512sum shasum ss ssh sshd stat sum swapon sysctl systemctl systeminfo timedatectl top tracepath tracepath6 traceroute traceroute6 tune2fs udevadm ufw uname update-alternatives upower uptime vdir veracrypt vmstat w wc wg who xrandr zipinfo zpool) + jc_commands=(acpi airport amixer apt-cache apt-get arp blkid bluetoothctl cbt certbot chage cksum crontab curl date debconf-show df dig dmidecode dpkg du efibootmgr env ethtool file findmnt finger free git gpg hciconfig host id ifconfig iostat ip ipconfig iptables iw iwconfig jobs last lastb ls lsattr lsb_release lsblk lsmod lsof lspci lsusb md5 md5sum mdadm mount mpstat needrestart netstat nmcli nsd-control ntpq os-prober pacman pidstat ping ping6 pip pip3 postconf printenv ps route rpm rsync sfdisk sha1sum sha224sum sha256sum sha384sum sha512sum shasum ss ssh sshd stat sum swapon sysctl systemctl systeminfo timedatectl top tracepath tracepath6 traceroute traceroute6 tune2fs udevadm ufw uname update-alternatives upower uptime vdir veracrypt vmstat w wc wg who xrandr zipinfo zpool) jc_commands_describe=( 'acpi:run "acpi" command with magic syntax.' 'airport:run "airport" command with magic syntax.' + 'amixer:run "amixer" command with magic syntax.' 'apt-cache:run "apt-cache" command with magic syntax.' 'apt-get:run "apt-get" command with magic syntax.' 'arp:run "arp" command with magic syntax.' @@ -124,11 +125,12 @@ _jc() { 'zipinfo:run "zipinfo" command with magic syntax.' 'zpool:run "zpool" command with magic syntax.' ) - jc_parsers=(--acpi --airport --airport-s --apt-cache-show --apt-get-sqq --arp --asciitable --asciitable-m --blkid --bluetoothctl --cbt --cef --cef-s --certbot --chage --cksum --clf --clf-s --crontab --crontab-u --csv --csv-s --curl-head --date --datetime-iso --debconf-show --df --dig --dir --dmidecode --dpkg-l --du --efibootmgr --email-address --env --ethtool --file --find --findmnt --finger --free --fstab --git-log --git-log-s --git-ls-remote --gpg --group --gshadow --hash --hashsum --hciconfig --history --host --hosts --http-headers --id --ifconfig --ini --ini-dup --iostat --iostat-s --ip-address --ipconfig --iptables --ip-route --iw-scan --iwconfig --jar-manifest --jobs --jwt --kv --kv-dup --last --ls --ls-s --lsattr --lsb-release --lsblk --lsmod --lsof --lspci --lsusb --m3u --mdadm --mount --mpstat --mpstat-s --needrestart --netstat --nmcli --nsd-control --ntpq --openvpn --os-prober --os-release --pacman --passwd --path --path-list --pci-ids --pgpass --pidstat --pidstat-s --ping --ping-s --pip-list --pip-show --pkg-index-apk --pkg-index-deb --plist --postconf --proc --proc-buddyinfo --proc-cmdline --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 --swapon --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 --tune2fs --udevadm --ufw --ufw-appinfo --uname --update-alt-gs --update-alt-q --upower --uptime --url --ver --veracrypt --vmstat --vmstat-s --w --wc --wg-show --who --x509-cert --x509-csr --xml --xrandr --yaml --zipinfo --zpool-iostat --zpool-status) + jc_parsers=(--acpi --airport --airport-s --amixer --apt-cache-show --apt-get-sqq --arp --asciitable --asciitable-m --blkid --bluetoothctl --cbt --cef --cef-s --certbot --chage --cksum --clf --clf-s --crontab --crontab-u --csv --csv-s --curl-head --date --datetime-iso --debconf-show --df --dig --dir --dmidecode --dpkg-l --du --efibootmgr --email-address --env --ethtool --file --find --findmnt --finger --free --fstab --git-log --git-log-s --git-ls-remote --gpg --group --gshadow --hash --hashsum --hciconfig --history --host --hosts --http-headers --id --ifconfig --ini --ini-dup --iostat --iostat-s --ip-address --ipconfig --iptables --ip-route --iw-scan --iwconfig --jar-manifest --jobs --jwt --kv --kv-dup --last --ls --ls-s --lsattr --lsb-release --lsblk --lsmod --lsof --lspci --lsusb --m3u --mdadm --mount --mpstat --mpstat-s --needrestart --netstat --nmcli --nsd-control --ntpq --openvpn --os-prober --os-release --pacman --passwd --path --path-list --pci-ids --pgpass --pidstat --pidstat-s --ping --ping-s --pip-list --pip-show --pkg-index-apk --pkg-index-deb --plist --postconf --proc --proc-buddyinfo --proc-cmdline --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 --swapon --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 --tune2fs --udevadm --ufw --ufw-appinfo --uname --update-alt-gs --update-alt-q --upower --uptime --url --ver --veracrypt --vmstat --vmstat-s --w --wc --wg-show --who --x509-cert --x509-csr --xml --xrandr --yaml --zipinfo --zpool-iostat --zpool-status) jc_parsers_describe=( '--acpi:`acpi` command parser' '--airport:`airport -I` command parser' '--airport-s:`airport -s` command parser' + '--amixer:`amixer` command parser' '--apt-cache-show:`apt-cache show` command parser' '--apt-get-sqq:`apt-get -sqq` command parser' '--arp:`arp` command parser' diff --git a/docs/parsers/amixer.md b/docs/parsers/amixer.md new file mode 100644 index 00000000..71473eb2 --- /dev/null +++ b/docs/parsers/amixer.md @@ -0,0 +1,117 @@ +[Home](https://kellyjonbrazil.github.io/jc/) + + +# jc.parsers.amixer + +jc - JSON Convert `amixer sget` command output parser + +Usage (cli): + + $ amixer sget | jc --amixer + $ amixer sget Master | jc --amixer + $ amixer sget Capture | jc --amixer + $ amixer sget Speakers | jc --amixer + +Usage (module): + + import jc + result = jc.parse('amixer', ) + +Schema: + + { + "control_name": string, + "capabilities": [ + string + ], + "playback_channels": [ + string + ], + "limits": { + "playback_min": integer, + "playback_max": integer + }, + "mono": { + "playback_value": integer, + "percentage": integer, + "db": float, + "status": boolean + } + } + +Examples: + + $ amixer sget Master | jc --amixer -p + { + "control_name": "Capture", + "capabilities": [ + "cvolume", + "cswitch" + ], + "playback_channels": [], + "limits": { + "playback_min": 0, + "playback_max": 63 + }, + "front_left": { + "playback_value": 63, + "percentage": 100, + "db": 30.0, + "status": true + }, + "front_right": { + "playback_value": 63, + "percentage": 100, + "db": 30.0, + "status": true + } + } + + $ amixer sget Master | jc --amixer -p -r + { + "control_name": "Master", + "capabilities": [ + "pvolume", + "pvolume-joined", + "pswitch", + "pswitch-joined" + ], + "playback_channels": [ + "Mono" + ], + "limits": { + "playback_min": "0", + "playback_max": "87" + }, + "mono": { + "playback_value": "87", + "percentage": "100%", + "db": "0.00db", + "status": "on" + } + } + + + +### parse + +```python +def parse(data: str, raw: bool = False, quiet: bool = False) -> Dict +``` + +Main text parsing function + +Parameters: + data: (string) text data to parse + raw: (boolean) unprocessed output if True + quiet: (boolean) suppress warning messages if True + +Returns: + Dictionary. Raw or processed structured data. + +### Parser Information +Compatibility: linux + +Source: [`jc/parsers/amixer.py`](https://github.com/kellyjonbrazil/jc/blob/master/jc/parsers/amixer.py) + +Version 1.0 by Eden Refael (edenraf@hotmail.com) diff --git a/docs/parsers/bluetoothctl.md b/docs/parsers/bluetoothctl.md index fc82d38b..428493f8 100644 --- a/docs/parsers/bluetoothctl.md +++ b/docs/parsers/bluetoothctl.md @@ -136,4 +136,4 @@ Compatibility: linux Source: [`jc/parsers/bluetoothctl.py`](https://github.com/kellyjonbrazil/jc/blob/master/jc/parsers/bluetoothctl.py) -Version 1.3 by Jake Ob (iakopap at gmail.com) +Version 1.4 by Jake Ob (iakopap at gmail.com) diff --git a/docs/parsers/iptables.md b/docs/parsers/iptables.md index 8c41a330..b1ea0ad9 100644 --- a/docs/parsers/iptables.md +++ b/docs/parsers/iptables.md @@ -25,6 +25,9 @@ Schema: [ { "chain": string, + "default_policy": string, + "default_packets": integer, + "default_bytes": integer, "rules": [ { "num" integer, @@ -49,6 +52,9 @@ Examples: [ { "chain": "PREROUTING", + "default_policy": "DROP", + "default_packets": 0, + "default_bytes": 0, "rules": [ { "num": 1, @@ -108,6 +114,9 @@ Examples: [ { "chain": "PREROUTING", + "default_policy": "DROP", + "default_packets": "0", + "default_bytes": "0", "rules": [ { "num": "1", @@ -188,4 +197,4 @@ Compatibility: linux Source: [`jc/parsers/iptables.py`](https://github.com/kellyjonbrazil/jc/blob/master/jc/parsers/iptables.py) -Version 1.11 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.12 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/lsblk.md b/docs/parsers/lsblk.md index 6b128150..2fcebda2 100644 --- a/docs/parsers/lsblk.md +++ b/docs/parsers/lsblk.md @@ -22,46 +22,53 @@ Schema: [ { - "name": string, - "maj_min": string, - "rm": boolean, - "size": string, - "ro": boolean, - "type": string, - "mountpoint": string, - "kname": string, - "fstype": string, - "label": string, - "uuid": string, - "partlabel": string, - "partuuid": string, - "ra": integer, - "model": string, - "serial": string, - "state": string, - "owner": string, - "group": string, - "mode": string, - "alignment": integer, - "min_io": integer, - "opt_io": integer, - "phy_sec": integer, - "log_sec": integer, - "rota": boolean, - "sched": string, - "rq_size": integer, - "disc_aln": integer, - "disc_gran": string, - "disc_max": string, - "disc_zero": boolean, - "wsame": string, - "wwn": string, - "rand": boolean, - "pkname": string, - "hctl": string, - "tran": string, - "rev": string, - "vendor": string + "name": string, + "maj_min": string, + "rm": boolean, + "size": string, + "size_bytes": integer + "ro": boolean, + "type": string, + "mountpoint": string, + "mountpoints": [ + string + ], + "kname": string, + "fstype": string, + "label": string, + "uuid": string, + "partlabel": string, + "partuuid": string, + "ra": integer, + "model": string, + "serial": string, + "state": string, + "owner": string, + "group": string, + "mode": string, + "alignment": integer, + "min_io": integer, + "opt_io": integer, + "phy_sec": integer, + "log_sec": integer, + "rota": boolean, + "sched": string, + "rq_size": integer, + "disc_aln": integer, + "disc_gran": string, + "disc_gran_bytes": integer, + "disc_max": string, + "disc_max_bytes": integer, + "disc_zero": boolean, + "wsame": string, + "wsame_bytes": integer, + "wwn": string, + "rand": boolean, + "pkname": string, + "hctl": string, + "tran": string, + "rev": string, + "vendor": string } ] @@ -74,6 +81,7 @@ Examples: "maj_min": "8:0", "rm": false, "size": "20G", + "size_bytes": 20000000000, "ro": false, "type": "disk", "mountpoint": null @@ -83,6 +91,7 @@ Examples: "maj_min": "8:1", "rm": false, "size": "1G", + "size_bytes": 1000000000 "ro": false, "type": "part", "mountpoint": "/boot" @@ -100,6 +109,7 @@ Examples: "maj_min": "8:0", "rm": false, "size": "20G", + "size_bytes": 20000000000, "ro": false, "type": "disk", "mountpoint": null, @@ -126,9 +136,12 @@ Examples: "rq_size": 128, "disc_aln": 0, "disc_gran": "0B", + "disc_gran_bytes": 0, "disc_max": "0B", + "disc_max_bytes": 0, "disc_zero": false, "wsame": "32M", + "wsame_bytes": 32000000, "wwn": null, "rand": true, "pkname": null, @@ -142,6 +155,7 @@ Examples: "maj_min": "8:1", "rm": false, "size": "1G", + "size_bytes": 1000000000 "ro": false, "type": "part", "mountpoint": "/boot", @@ -168,9 +182,12 @@ Examples: "rq_size": 128, "disc_aln": 0, "disc_gran": "0B", + "disc_gran_bytes": 0, "disc_max": "0B", + "disc_max_bytes": 0, "disc_zero": false, "wsame": "32M", + "wsame_bytes": 32000000, "wwn": null, "rand": true, "pkname": "sda", @@ -192,6 +209,7 @@ Examples: "maj_min": "8:0", "rm": "0", "size": "20G", + "size_bytes": 20000000000, "ro": "0", "type": "disk", "mountpoint": null, @@ -218,9 +236,12 @@ Examples: "rq_size": "128", "disc_aln": "0", "disc_gran": "0B", + "disc_gran_bytes": 0, "disc_max": "0B", + "disc_max_bytes": 0, "disc_zero": "0", "wsame": "32M", + "wsame_bytes": 32000000, "wwn": null, "rand": "1", "pkname": null, @@ -234,6 +255,7 @@ Examples: "maj_min": "8:1", "rm": "0", "size": "1G", + "size_bytes": 1000000000 "ro": "0", "type": "part", "mountpoint": "/boot", @@ -260,9 +282,12 @@ Examples: "rq_size": "128", "disc_aln": "0", "disc_gran": "0B", + "disc_gran_bytes": 0, "disc_max": "0B", + "disc_max_bytes": 0, "disc_zero": "0", "wsame": "32M", + "wsame_bytes": 32000000, "wwn": null, "rand": "1", "pkname": "sda", @@ -299,4 +324,4 @@ Compatibility: linux Source: [`jc/parsers/lsblk.py`](https://github.com/kellyjonbrazil/jc/blob/master/jc/parsers/lsblk.py) -Version 1.9 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.10 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/mount.md b/docs/parsers/mount.md index fd61b63d..803c735b 100644 --- a/docs/parsers/mount.md +++ b/docs/parsers/mount.md @@ -100,4 +100,4 @@ Compatibility: linux, darwin, freebsd, aix Source: [`jc/parsers/mount.py`](https://github.com/kellyjonbrazil/jc/blob/master/jc/parsers/mount.py) -Version 1.10 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.11 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/nmcli.md b/docs/parsers/nmcli.md index 6473b2d7..4df779a1 100644 --- a/docs/parsers/nmcli.md +++ b/docs/parsers/nmcli.md @@ -41,6 +41,7 @@ These are documented below. [ { "": string/integer/float, # [0] + "team_config": object, "dhcp4_option_x": { "name": string, "value": string/integer/float, @@ -170,4 +171,4 @@ Compatibility: linux Source: [`jc/parsers/nmcli.py`](https://github.com/kellyjonbrazil/jc/blob/master/jc/parsers/nmcli.py) -Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/time.md b/docs/parsers/time.md index 1e2c3b43..8ea33f10 100644 --- a/docs/parsers/time.md +++ b/docs/parsers/time.md @@ -157,4 +157,4 @@ Compatibility: linux, darwin, cygwin, aix, freebsd Source: [`jc/parsers/time.py`](https://github.com/kellyjonbrazil/jc/blob/master/jc/parsers/time.py) -Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/x509_cert.md b/docs/parsers/x509_cert.md index a9d23725..d9e303d3 100644 --- a/docs/parsers/x509_cert.md +++ b/docs/parsers/x509_cert.md @@ -435,4 +435,4 @@ Compatibility: linux, darwin, cygwin, win32, aix, freebsd Source: [`jc/parsers/x509_cert.py`](https://github.com/kellyjonbrazil/jc/blob/master/jc/parsers/x509_cert.py) -Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/jc/cli.py b/jc/cli.py index 72ef7997..855aaa78 100644 --- a/jc/cli.py +++ b/jc/cli.py @@ -52,7 +52,7 @@ class info(): author: str = 'Kelly Brazil' author_email: str = 'kellyjonbrazil@gmail.com' website: str = 'https://github.com/kellyjonbrazil/jc' - copyright: str = '© 2019-2024 Kelly Brazil' + copyright: str = '© 2019-2025 Kelly Brazil' license: str = 'MIT License' diff --git a/jc/lib.py b/jc/lib.py index ff0b8807..8a01282a 100644 --- a/jc/lib.py +++ b/jc/lib.py @@ -10,7 +10,7 @@ from jc import appdirs from jc import utils -__version__ = '1.25.4' +__version__ = '1.25.5' parsers: List[str] = [ 'acpi', diff --git a/jc/parsers/amixer.py b/jc/parsers/amixer.py index e65811bb..b7818cf9 100644 --- a/jc/parsers/amixer.py +++ b/jc/parsers/amixer.py @@ -10,7 +10,7 @@ Usage (cli): Usage (module): import jc - result = jc.parse('amixer', ) + result = jc.parse('amixer', ) Schema: @@ -20,7 +20,7 @@ Schema: string ], "playback_channels": [ - string + string ], "limits": { "playback_min": integer, @@ -85,13 +85,12 @@ Examples: "status": "on" } } - - """ -from typing import List, Dict +from typing import Dict import jc.utils from jc.utils import convert_to_int +from jc.exceptions import ParseError class info(): """Provides parser metadata (version, author, etc.)""" @@ -107,7 +106,7 @@ class info(): __version__ = info.version -def _process(proc_data: dict) -> dict: +def _process(proc_data: Dict) -> Dict: """ Processes raw structured data to match the schema requirements. @@ -117,6 +116,9 @@ def _process(proc_data: dict) -> dict: Returns: (dict) processed structured data adhering to the schema """ + if not proc_data: + return {} + # Initialize the processed dictionary processed = { "control_name": proc_data.get("control_name", ""), @@ -147,20 +149,17 @@ def parse( data: str, raw: bool = False, quiet: bool = False -) -> List[Dict]: +) -> Dict: """ - Main text parsing function, The amixer is alsa mixer tool and output, Will work with Linux OS only. - + 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. - push test + Dictionary. Raw or processed structured data. """ """ The Algorithm for parsing the `amixer sget` command, Input Explained/Rules/Pseudo Algorithm: @@ -172,7 +171,6 @@ def parse( 3b. Playback channels - List of channels 4. Limits - We'll always have the minimum limit and the maximum limit. - Input Example: 1."":~$ amixer sget Capture Simple mixer control 'Capture',0 @@ -182,9 +180,6 @@ def parse( Front Left: Capture 63 [100%] [30.00db] [on] Front Right: Capture 63 [100%] [30.00db] [on] - - - 2."":~$ amixer sget Master Simple mixer control 'Master',0 Capabilities: pvolume pvolume-joined pswitch pswitch-joined @@ -192,10 +187,6 @@ def parse( Limits: Playback 0 - 87 Mono: Playback 87 [100%] [0.00db] [on] - - - - 3."":~$ amixer sget Speaker Simple mixer control 'Speaker',0 Capabilities: pvolume pswitch @@ -205,9 +196,6 @@ def parse( Front Left: Playback 87 [100%] [0.00db] [on] Front Right: Playback 87 [100%] [0.00db] [on] - - - 4."":~$ amixer sget Headphone Simple mixer control 'Headphone',0 Capabilities: pvolume pswitch @@ -224,54 +212,62 @@ def parse( jc.utils.input_type_check(data) # starts the parsing from here - mapping = {} - # split lines and than work on each line - lines = data.splitlines() - first_line = lines[0].strip() + mapping: Dict = {} - # Extract the control name from the first line - if first_line.startswith("Simple mixer control"): - control_name = first_line.split("'")[1] - else: - raise ValueError("Invalid amixer output format: missing control name.") - # map the control name - mapping["control_name"] = control_name + if jc.utils.has_data(data): + # split lines and than work on each line + lines = data.splitlines() + first_line = lines[0].strip() - # Process subsequent lines for capabilities, channels, limits, and channel-specific mapping. - # gets the lines from the next line - because we already took care the first line. - for line in lines[1:]: - # strip the line (maybe there are white spaces in the begin&end) - line = line.strip() + # Extract the control name from the first line + if first_line.startswith("Simple mixer control"): + control_name = first_line.split("'")[1] + else: + raise ParseError("Invalid amixer output format: missing control name.") + # map the control name + mapping["control_name"] = control_name - if line.startswith("Capabilities:"): - mapping["capabilities"] = line.split(":")[1].strip().split() - elif line.startswith("Playback channels:"): - mapping["playback_channels"] = line.split(":")[1].strip().split(" - ") - elif line.startswith("Limits:"): - limits = line.split(":")[1].strip().split(" - ") - mapping["limits"] = { - "playback_min": limits[0].split()[1], - "playback_max": limits[1] - } - elif line.startswith("Mono:") or line.startswith("Front Left:") or line.startswith("Front Right:"): - # Identify the channel name and parse its information - channel_name = line.split(":")[0].strip().lower().replace(" ", "_") - channel_info = line.split(":")[1].strip() - # Example: "Playback 255 [100%] [0.00db] [on]" - channel_data = channel_info.split(" ") - if channel_data[0] == "": - continue - playback_value = channel_data[1] - percentage = channel_data[2].strip("[]") # Extract percentage e.g., "100%" - db_value = channel_data[3].strip("[]") # Extract db value e.g., "0.00db" - status = channel_data[4].strip("[]") # Extract status e.g., "on" or "off" + # Process subsequent lines for capabilities, channels, limits, and channel-specific mapping. + # gets the lines from the next line - because we already took care the first line. + for line in lines[1:]: + # strip the line (maybe there are white spaces in the begin&end) + line = line.strip() - # Store channel mapping in the dictionary - mapping[channel_name] = { - "playback_value": playback_value, - "percentage": percentage, - "db": db_value.lower(), - "status": status - } + if line.startswith("Capabilities:"): + mapping["capabilities"] = line.split(":")[1].strip().split() + elif line.startswith("Playback channels:"): + mapping["playback_channels"] = line.split(":")[1].strip().split(" - ") + elif line.startswith("Limits:"): + limits = line.split(":")[1].strip().split(" - ") + mapping["limits"] = { + "playback_min": limits[0].split()[1], + "playback_max": limits[1] + } + elif line.startswith("Mono:") or line.startswith("Front Left:") or line.startswith("Front Right:"): + # Identify the channel name and parse its information + channel_name = line.split(":")[0].strip().lower().replace(" ", "_") + channel_info = line.split(":")[1].strip() + # Example: "Playback 255 [100%] [0.00db] [on]" + channel_data = channel_info.split(" ") + if channel_data[0] == "": + continue + + if "dB" in channel_data[3]: + db_value = channel_data[3].strip("[]") + status = channel_data[4].strip("[]") + else: + db_value = "0.0db" + status = channel_data[3].strip("[]") + + playback_value = channel_data[1] + percentage = channel_data[2].strip("[]") # Extract percentage e.g., "100%" + + # Store channel mapping in the dictionary + mapping[channel_name] = { + "playback_value": playback_value, + "percentage": percentage, + "db": db_value.lower(), + "status": status + } return mapping if raw else _process(mapping) diff --git a/jc/parsers/asn1crypto/x509.py b/jc/parsers/asn1crypto/x509.py index 563fa3bd..07beee6f 100644 --- a/jc/parsers/asn1crypto/x509.py +++ b/jc/parsers/asn1crypto/x509.py @@ -255,7 +255,7 @@ class EmailAddress(IA5String): # fix to allow incorrectly encoded email addresses to succeed with warning try: self._unicode = mailbox.decode('cp1252') + '@' + hostname.decode('idna') - except UnicodeDecodeError: + except (UnicodeDecodeError, UnicodeError): ascii_mailbox = mailbox.decode('ascii', errors='backslashreplace') ascii_hostname = hostname.decode('ascii', errors='backslashreplace') from jc.utils import warning_message diff --git a/jc/parsers/bluetoothctl.py b/jc/parsers/bluetoothctl.py index 3d241334..16943bcb 100644 --- a/jc/parsers/bluetoothctl.py +++ b/jc/parsers/bluetoothctl.py @@ -112,7 +112,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.3' + version = '1.4' description = '`bluetoothctl` command parser' author = 'Jake Ob' author_email = 'iakopap at gmail.com' @@ -139,6 +139,7 @@ try: "alias": str, "class": str, "powered": str, + "power_state": str, "discoverable": str, "discoverable_timeout": str, "pairable": str, @@ -185,6 +186,7 @@ _controller_line_pattern = ( + r"|\s*Alias:\s*(?P.+)" + r"|\s*Class:\s*(?P.+)" + r"|\s*Powered:\s*(?P.+)" + + r"|\s*PowerState:\s*(?P.+)" + r"|\s*Discoverable:\s*(?P.+)" + r"|\s*DiscoverableTimeout:\s*(?P.+)" + r"|\s*Pairable:\s*(?P.+)" @@ -219,6 +221,7 @@ def _parse_controller(next_lines: List[str]) -> Optional[Controller]: "alias": '', "class": '', "powered": '', + "power_state": '', "discoverable": '', "discoverable_timeout": '', "pairable": '', @@ -261,6 +264,8 @@ def _parse_controller(next_lines: List[str]) -> Optional[Controller]: controller["class"] = matches["class"] elif matches["powered"]: controller["powered"] = matches["powered"] + elif matches["power_state"]: + controller["power_state"] = matches["power_state"] elif matches["discoverable"]: controller["discoverable"] = matches["discoverable"] elif matches["discoverable_timeout"]: diff --git a/jc/parsers/iptables.py b/jc/parsers/iptables.py index dcaab5eb..9dd8b7b5 100644 --- a/jc/parsers/iptables.py +++ b/jc/parsers/iptables.py @@ -20,6 +20,9 @@ Schema: [ { "chain": string, + "default_policy": string, + "default_packets": integer, + "default_bytes": integer, "rules": [ { "num" integer, @@ -44,6 +47,9 @@ Examples: [ { "chain": "PREROUTING", + "default_policy": "DROP", + "default_packets": 0, + "default_bytes": 0, "rules": [ { "num": 1, @@ -103,6 +109,9 @@ Examples: [ { "chain": "PREROUTING", + "default_policy": "DROP", + "default_packets": "0", + "default_bytes": "0", "rules": [ { "num": "1", @@ -158,12 +167,13 @@ Examples: ... ] """ +import re import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.11' + version = '1.12' description = '`iptables` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -174,6 +184,17 @@ class info(): __version__ = info.version +chain_pkt_byt_pattern = re.compile( + r''' + \s\(policy\s + (?P.+) + \s + (?P.+) + \spackets,\s + (?P.+) + \sbytes\) + ''', re.VERBOSE +) def _process(proc_data): """ @@ -188,6 +209,13 @@ def _process(proc_data): List of Dictionaries. Structured data to conform to the schema. """ for entry in proc_data: + + if 'default_packets' in entry: + entry['default_packets'] = jc.utils.convert_to_int(entry['default_packets']) + + if 'default_bytes' in entry: + entry['default_bytes'] = jc.utils.convert_size_to_int(entry['default_bytes']) + for rule in entry['rules']: int_list = ['num', 'pkts'] for key in rule: @@ -243,6 +271,14 @@ def parse(data, raw=False, quiet=False): parsed_line = line.split() chain['chain'] = parsed_line[1] + + stats_match = re.search(chain_pkt_byt_pattern, line) + if stats_match: + stats = stats_match.groupdict() + chain['default_policy'] = stats['policy_name'] + chain['default_packets'] = stats['packets'] + chain['default_bytes'] = stats['bytes'] + chain['rules'] = [] continue diff --git a/jc/parsers/lsblk.py b/jc/parsers/lsblk.py index f25e0e02..a56bdb9a 100644 --- a/jc/parsers/lsblk.py +++ b/jc/parsers/lsblk.py @@ -17,46 +17,53 @@ Schema: [ { - "name": string, - "maj_min": string, - "rm": boolean, - "size": string, - "ro": boolean, - "type": string, - "mountpoint": string, - "kname": string, - "fstype": string, - "label": string, - "uuid": string, - "partlabel": string, - "partuuid": string, - "ra": integer, - "model": string, - "serial": string, - "state": string, - "owner": string, - "group": string, - "mode": string, - "alignment": integer, - "min_io": integer, - "opt_io": integer, - "phy_sec": integer, - "log_sec": integer, - "rota": boolean, - "sched": string, - "rq_size": integer, - "disc_aln": integer, - "disc_gran": string, - "disc_max": string, - "disc_zero": boolean, - "wsame": string, - "wwn": string, - "rand": boolean, - "pkname": string, - "hctl": string, - "tran": string, - "rev": string, - "vendor": string + "name": string, + "maj_min": string, + "rm": boolean, + "size": string, + "size_bytes": integer + "ro": boolean, + "type": string, + "mountpoint": string, + "mountpoints": [ + string + ], + "kname": string, + "fstype": string, + "label": string, + "uuid": string, + "partlabel": string, + "partuuid": string, + "ra": integer, + "model": string, + "serial": string, + "state": string, + "owner": string, + "group": string, + "mode": string, + "alignment": integer, + "min_io": integer, + "opt_io": integer, + "phy_sec": integer, + "log_sec": integer, + "rota": boolean, + "sched": string, + "rq_size": integer, + "disc_aln": integer, + "disc_gran": string, + "disc_gran_bytes": integer, + "disc_max": string, + "disc_max_bytes": integer, + "disc_zero": boolean, + "wsame": string, + "wsame_bytes": integer, + "wwn": string, + "rand": boolean, + "pkname": string, + "hctl": string, + "tran": string, + "rev": string, + "vendor": string } ] @@ -69,6 +76,7 @@ Examples: "maj_min": "8:0", "rm": false, "size": "20G", + "size_bytes": 20000000000, "ro": false, "type": "disk", "mountpoint": null @@ -78,6 +86,7 @@ Examples: "maj_min": "8:1", "rm": false, "size": "1G", + "size_bytes": 1000000000 "ro": false, "type": "part", "mountpoint": "/boot" @@ -95,6 +104,7 @@ Examples: "maj_min": "8:0", "rm": false, "size": "20G", + "size_bytes": 20000000000, "ro": false, "type": "disk", "mountpoint": null, @@ -121,9 +131,12 @@ Examples: "rq_size": 128, "disc_aln": 0, "disc_gran": "0B", + "disc_gran_bytes": 0, "disc_max": "0B", + "disc_max_bytes": 0, "disc_zero": false, "wsame": "32M", + "wsame_bytes": 32000000, "wwn": null, "rand": true, "pkname": null, @@ -137,6 +150,7 @@ Examples: "maj_min": "8:1", "rm": false, "size": "1G", + "size_bytes": 1000000000 "ro": false, "type": "part", "mountpoint": "/boot", @@ -163,9 +177,12 @@ Examples: "rq_size": 128, "disc_aln": 0, "disc_gran": "0B", + "disc_gran_bytes": 0, "disc_max": "0B", + "disc_max_bytes": 0, "disc_zero": false, "wsame": "32M", + "wsame_bytes": 32000000, "wwn": null, "rand": true, "pkname": "sda", @@ -187,6 +204,7 @@ Examples: "maj_min": "8:0", "rm": "0", "size": "20G", + "size_bytes": 20000000000, "ro": "0", "type": "disk", "mountpoint": null, @@ -213,9 +231,12 @@ Examples: "rq_size": "128", "disc_aln": "0", "disc_gran": "0B", + "disc_gran_bytes": 0, "disc_max": "0B", + "disc_max_bytes": 0, "disc_zero": "0", "wsame": "32M", + "wsame_bytes": 32000000, "wwn": null, "rand": "1", "pkname": null, @@ -229,6 +250,7 @@ Examples: "maj_min": "8:1", "rm": "0", "size": "1G", + "size_bytes": 1000000000 "ro": "0", "type": "part", "mountpoint": "/boot", @@ -255,9 +277,12 @@ Examples: "rq_size": "128", "disc_aln": "0", "disc_gran": "0B", + "disc_gran_bytes": 0, "disc_max": "0B", + "disc_max_bytes": 0, "disc_zero": "0", "wsame": "32M", + "wsame_bytes": 32000000, "wwn": null, "rand": "1", "pkname": "sda", @@ -275,7 +300,7 @@ import jc.parsers.universal class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.9' + version = '1.10' description = '`lsblk` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -304,14 +329,19 @@ def _process(proc_data): int_list = {'ra', 'alignment', 'min_io', 'opt_io', 'phy_sec', 'log_sec', 'rq_size', 'disc_aln'} + size_list = {'size', 'disc_gran', 'disc_max', 'wsame'} + for entry in proc_data: - for key in entry: + for key in entry.copy(): if key in bool_list: entry[key] = jc.utils.convert_to_bool(entry[key]) if key in int_list: entry[key] = jc.utils.convert_to_int(entry[key]) + if key in size_list: + entry[key + '_bytes'] = jc.utils.convert_size_to_int(entry[key], posix_mode=True) + return proc_data @@ -335,6 +365,7 @@ def parse(data, raw=False, quiet=False): # Clear any blank lines cleandata = list(filter(None, data.splitlines())) raw_output = [] + new_list = [] if jc.utils.has_data(data): @@ -346,11 +377,23 @@ def parse(data, raw=False, quiet=False): raw_output = jc.parsers.universal.sparse_table_parse(cleandata) - # clean up non-ascii characters, if any + # find multiple mount points and add to a single entry for entry in raw_output: - entry['name'] = entry['name'].encode('ascii', errors='ignore').decode() + if entry['name']: + if 'mountpoints' in entry: + if entry['mountpoints']: + entry['mountpoints'] = [entry['mountpoints']] + else: + entry['mountpoints'] = [] + new_list.append(entry) + elif 'mountpoints' in entry and entry['mountpoints']: + new_list[-1]['mountpoints'].append(entry['mountpoints']) - if raw: - return raw_output - else: - return _process(raw_output) + # clean up tree characters, if any + for entry in new_list: + tree_chars = ['`-', '|-', '├─', '└─'] + for chars in tree_chars: + if entry['name'][0:2] == chars: + entry['name'] = entry['name'][2:] + + return new_list if raw else _process(new_list) diff --git a/jc/parsers/mount.py b/jc/parsers/mount.py index 9fe67558..3837975c 100644 --- a/jc/parsers/mount.py +++ b/jc/parsers/mount.py @@ -71,13 +71,12 @@ Example: ] """ import re - import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.10' + version = '1.11' description = '`mount` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -111,19 +110,24 @@ def _osx_parse(data): for entry in data: output_line = {} - filesystem = entry.split(' on ') - filesystem = filesystem[0] - output_line['filesystem'] = filesystem + pattern = re.compile( + r''' + (?P.*) + \son\s + (?P.*?) + \s + \((?P.*?)\)\s* + ''', re.VERBOSE + ) - mount_point = entry.split(' on ') - mount_point = mount_point[1].split(' (') - mount_point = mount_point[0] - output_line['mount_point'] = mount_point + mymatch = pattern.match(entry) + groups = mymatch.groupdict() - options = entry.split('(', maxsplit=1) - options = options[1].rstrip(')') - options = options.split(', ') - output_line['options'] = options + if groups: + output_line['filesystem'] = groups['filesystem'] + output_line['mount_point'] = groups['mount_point'] + options = groups['options'].split(', ') + output_line['options'] = options output.append(output_line) @@ -218,7 +222,7 @@ def parse(data, raw=False, quiet=False): # check for OSX and AIX output if ' type ' not in cleandata[0]: - if 'node' in cleandata[0]: + if ' node ' in cleandata[0]: raw_output = _aix_parse(cleandata) else: raw_output = _osx_parse(cleandata) diff --git a/jc/parsers/nmcli.py b/jc/parsers/nmcli.py index 4779725a..16c85407 100644 --- a/jc/parsers/nmcli.py +++ b/jc/parsers/nmcli.py @@ -36,6 +36,7 @@ These are documented below. [ { "": string/integer/float, # [0] + "team_config": object, "dhcp4_option_x": { "name": string, "value": string/integer/float, @@ -141,6 +142,7 @@ Examples: ] """ import re +import json from typing import List, Dict, Optional import jc.utils from jc.parsers.universal import sparse_table_parse @@ -149,7 +151,7 @@ from jc.exceptions import ParseError class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.0' + version = '1.1' description = '`nmcli` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -313,8 +315,30 @@ def _device_show_parse(data: str) -> List[Dict]: def _connection_show_x_parse(data: str) -> List[Dict]: raw_output: List = [] item: Dict = {} + in_team_config: bool = False + team_config_value: List = [] for line in filter(None, data.splitlines()): + + # fix for team.config, which is multi-line JSON + if line.startswith('team.config:'): + in_team_config = True + _, value = line.split(':', maxsplit=1) + team_config_value.append(value.strip()) + item['team_config'] = {} + continue + + if not line.startswith('team.') and in_team_config: + team_config_value.append(line.strip()) + continue + + in_team_config = False + + if team_config_value: + # team.config value should always be JSON + item['team_config'] = json.loads(''.join(team_config_value)) + team_config_value = [] + key, value = line.split(':', maxsplit=1) key_n = _normalize_key(key) diff --git a/jc/parsers/pyedid/edid.py b/jc/parsers/pyedid/edid.py index dbed2f0a..13dbf8f7 100755 --- a/jc/parsers/pyedid/edid.py +++ b/jc/parsers/pyedid/edid.py @@ -4,7 +4,6 @@ Edid module import struct from collections import namedtuple -from typing import ByteString __all__ = ["Edid"] @@ -108,10 +107,10 @@ class Edid: ), ) - def __init__(self, edid: ByteString): + def __init__(self, edid: bytes): self._parse_edid(edid) - def _parse_edid(self, edid: ByteString): + def _parse_edid(self, edid: bytes): """Convert edid byte string to edid object""" if struct.calcsize(self._STRUCT_FORMAT) != 128: raise ValueError("Wrong edid size.") diff --git a/jc/parsers/pyedid/helpers/edid_helper.py b/jc/parsers/pyedid/helpers/edid_helper.py index b4165ca9..b8f28572 100644 --- a/jc/parsers/pyedid/helpers/edid_helper.py +++ b/jc/parsers/pyedid/helpers/edid_helper.py @@ -3,7 +3,7 @@ EDID helper """ from subprocess import CalledProcessError, check_output -from typing import ByteString, List +from typing import List __all__ = ["EdidHelper"] @@ -12,14 +12,14 @@ class EdidHelper: """Class for working with EDID data""" @staticmethod - def hex2bytes(hex_data: str) -> ByteString: + def hex2bytes(hex_data: str) -> bytes: """Convert hex EDID string to bytes Args: hex_data (str): hex edid string Returns: - ByteString: edid byte string + bytes: edid byte string """ # delete edid 1.3 additional block if len(hex_data) > 256: @@ -32,14 +32,14 @@ class EdidHelper: return bytes(numbers) @classmethod - def get_edids(cls) -> List[ByteString]: + def get_edids(cls) -> List[bytes]: """Get edids from xrandr Raises: `RuntimeError`: if error with retrieving xrandr util data Returns: - List[ByteString]: list with edids + List[bytes]: list with edids """ try: output = check_output(["xrandr", "--verbose"]) diff --git a/jc/parsers/time.py b/jc/parsers/time.py index 539de8de..f93cbc02 100644 --- a/jc/parsers/time.py +++ b/jc/parsers/time.py @@ -132,7 +132,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.4' + version = '1.5' description = '`/usr/bin/time` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -171,13 +171,18 @@ def _process(proc_data): proc_data['command_being_timed'] = proc_data['command_being_timed'][1:-1] if 'elapsed_time' in proc_data: - proc_data['elapsed_time'] = proc_data['elapsed_time'].replace('.', ':') - *hours, minutes, seconds, centiseconds = proc_data['elapsed_time'].split(':') - proc_data['elapsed_time'] = proc_data['elapsed_time'][::-1].replace(':', '.', 1)[::-1] + *hours, minutes, ss = proc_data['elapsed_time'].split(':') + if '.' in ss: + seconds, centiseconds = ss.split('.') + else: + seconds = ss + centiseconds = '0' + if hours: proc_data['elapsed_time_hours'] = jc.utils.convert_to_int(hours[0]) else: proc_data['elapsed_time_hours'] = 0 + proc_data['elapsed_time_minutes'] = jc.utils.convert_to_int(minutes) proc_data['elapsed_time_seconds'] = jc.utils.convert_to_int(seconds) proc_data['elapsed_time_centiseconds'] = jc.utils.convert_to_int(centiseconds) diff --git a/jc/parsers/x509_cert.py b/jc/parsers/x509_cert.py index a60ce949..062503bb 100644 --- a/jc/parsers/x509_cert.py +++ b/jc/parsers/x509_cert.py @@ -413,7 +413,7 @@ from jc.parsers.asn1crypto import pem, x509, jc_global class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.3' + version = '1.4' description = 'X.509 PEM and DER certificate file parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' diff --git a/man/jc.1 b/man/jc.1 index 16b0ae41..48ea6f49 100644 --- a/man/jc.1 +++ b/man/jc.1 @@ -1,4 +1,4 @@ -.TH jc 1 2024-11-25 1.25.4 "JSON Convert" +.TH jc 1 2025-05-10 1.25.5 "JSON Convert" .SH NAME \fBjc\fP \- JSON Convert JSONifies the output of many CLI tools, file-types, and strings @@ -52,6 +52,11 @@ Parsers: \fB--airport-s\fP `airport -s` command parser +.TP +.B +\fB--amixer\fP +`amixer` command parser + .TP .B \fB--apt-cache-show\fP @@ -1632,6 +1637,6 @@ Kelly Brazil (kellyjonbrazil@gmail.com) https://github.com/kellyjonbrazil/jc .SH COPYRIGHT -Copyright (c) 2019-2024 Kelly Brazil +Copyright (c) 2019-2025 Kelly Brazil License: MIT License \ No newline at end of file diff --git a/runtests.sh b/runtests.sh index 05723cc4..2a97aa55 100755 --- a/runtests.sh +++ b/runtests.sh @@ -1,5 +1,5 @@ #!/bin/bash -# system should be in "America/Los_Angeles" timezone for all tests to pass -# ensure no local plugin parsers are installed for all tests to pass +# system should be in "America/Los_Angeles" (PST8PDT) timezone for all tests +# to pass ensure no local plugin parsers are installed for all tests to pass -TZ=America/Los_Angeles python3 -m unittest -v +TZ=PST8PDT python3 -m unittest -v diff --git a/setup.py b/setup.py index 321d2760..fa0d7cc7 100755 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ with open('README.md', 'r') as f: setuptools.setup( name='jc', - version='1.25.4', + version='1.25.5', 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/iptables-filter-nv.json b/tests/fixtures/centos-7.7/iptables-filter-nv.json index 329681f4..4f542493 100644 --- a/tests/fixtures/centos-7.7/iptables-filter-nv.json +++ b/tests/fixtures/centos-7.7/iptables-filter-nv.json @@ -1 +1 @@ -[{"chain": "INPUT", "rules": [{"pkts": 4175, "bytes": 1130000, "target": "ACCEPT", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "ctstate RELATED,ESTABLISHED"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "all", "opt": null, "in": "lo", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 2383, "bytes": 204000, "target": "INPUT_direct", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 2383, "bytes": 204000, "target": "INPUT_ZONES_SOURCE", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 2383, "bytes": 204000, "target": "INPUT_ZONES", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 0, "bytes": 0, "target": "DROP", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "ctstate INVALID"}, {"pkts": 2382, "bytes": 204000, "target": "REJECT", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "reject-with icmp-host-prohibited"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "all", "opt": null, "in": "lo", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "ctstate RELATED,ESTABLISHED"}, {"pkts": 0, "bytes": 0, "target": "DROP", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "ctstate INVALID"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "tcp", "opt": null, "in": "*", "out": "*", "source": "15.15.15.0/24", "destination": "0.0.0.0/0", "options": "tcp dpt:22 ctstate NEW,ESTABLISHED"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "all", "opt": null, "in": "lo", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "ctstate RELATED,ESTABLISHED"}, {"pkts": 0, "bytes": 0, "target": "DROP", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "ctstate INVALID"}, {"pkts": 0, "bytes": 0, "target": "DROP", "prot": "all", "opt": null, "in": "lo", "out": "*", "source": "15.15.15.51", "destination": "0.0.0.0/0"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "tcp", "opt": null, "in": "*", "out": "*", "source": "15.15.15.0/24", "destination": "0.0.0.0/0", "options": "tcp dpt:22 ctstate NEW,ESTABLISHED"}]}, {"chain": "FORWARD", "rules": [{"pkts": 0, "bytes": 0, "target": "DOCKER-ISOLATION", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 0, "bytes": 0, "target": "DOCKER", "prot": "all", "opt": null, "in": "*", "out": "docker0", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "all", "opt": null, "in": "*", "out": "docker0", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "ctstate RELATED,ESTABLISHED"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "all", "opt": null, "in": "docker0", "out": "!docker0", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "all", "opt": null, "in": "docker0", "out": "docker0", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "ctstate RELATED,ESTABLISHED"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "all", "opt": null, "in": "lo", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 0, "bytes": 0, "target": "FORWARD_direct", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 0, "bytes": 0, "target": "FORWARD_IN_ZONES_SOURCE", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 0, "bytes": 0, "target": "FORWARD_IN_ZONES", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 0, "bytes": 0, "target": "FORWARD_OUT_ZONES_SOURCE", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 0, "bytes": 0, "target": "FORWARD_OUT_ZONES", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 0, "bytes": 0, "target": "DROP", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "ctstate INVALID"}, {"pkts": 0, "bytes": 0, "target": "REJECT", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "reject-with icmp-host-prohibited"}]}, {"chain": "OUTPUT", "rules": [{"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "all", "opt": null, "in": "*", "out": "lo", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 3419, "bytes": 573000, "target": "OUTPUT_direct", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "all", "opt": null, "in": "*", "out": "lo", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 225, "bytes": 101000, "target": "ACCEPT", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "ctstate ESTABLISHED"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "tcp", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "tcp spt:22 ctstate ESTABLISHED"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "all", "opt": null, "in": "*", "out": "lo", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "ctstate ESTABLISHED"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "tcp", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "tcp spt:22 ctstate ESTABLISHED"}]}, {"chain": "DOCKER", "rules": []}, {"chain": "DOCKER-ISOLATION", "rules": [{"pkts": 0, "bytes": 0, "target": "RETURN", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}]}, {"chain": "FORWARD_IN_ZONES", "rules": [{"pkts": 0, "bytes": 0, "target": "FWDI_public", "prot": "all", "opt": null, "in": "ens33", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "[goto] "}, {"pkts": 0, "bytes": 0, "target": "FWDI_public", "prot": "all", "opt": null, "in": "+", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "[goto] "}]}, {"chain": "FORWARD_IN_ZONES_SOURCE", "rules": []}, {"chain": "FORWARD_OUT_ZONES", "rules": [{"pkts": 0, "bytes": 0, "target": "FWDO_public", "prot": "all", "opt": null, "in": "*", "out": "ens33", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "[goto] "}, {"pkts": 0, "bytes": 0, "target": "FWDO_public", "prot": "all", "opt": null, "in": "*", "out": "+", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "[goto] "}]}, {"chain": "FORWARD_OUT_ZONES_SOURCE", "rules": []}, {"chain": "FORWARD_direct", "rules": []}, {"chain": "FWDI_public", "rules": [{"pkts": 0, "bytes": 0, "target": "FWDI_public_log", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 0, "bytes": 0, "target": "FWDI_public_deny", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 0, "bytes": 0, "target": "FWDI_public_allow", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "icmp", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}]}, {"chain": "FWDI_public_allow", "rules": []}, {"chain": "FWDI_public_deny", "rules": []}, {"chain": "FWDI_public_log", "rules": []}, {"chain": "FWDO_public", "rules": [{"pkts": 0, "bytes": 0, "target": "FWDO_public_log", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 0, "bytes": 0, "target": "FWDO_public_deny", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 0, "bytes": 0, "target": "FWDO_public_allow", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}]}, {"chain": "FWDO_public_allow", "rules": []}, {"chain": "FWDO_public_deny", "rules": []}, {"chain": "FWDO_public_log", "rules": []}, {"chain": "INPUT_ZONES", "rules": [{"pkts": 2367, "bytes": 202000, "target": "IN_public", "prot": "all", "opt": null, "in": "ens33", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "[goto] "}, {"pkts": 1, "bytes": 330, "target": "IN_public", "prot": "all", "opt": null, "in": "+", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "[goto] "}]}, {"chain": "INPUT_ZONES_SOURCE", "rules": []}, {"chain": "INPUT_direct", "rules": []}, {"chain": "IN_public", "rules": [{"pkts": 2383, "bytes": 204000, "target": "IN_public_log", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 2383, "bytes": 204000, "target": "IN_public_deny", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 2383, "bytes": 204000, "target": "IN_public_allow", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "icmp", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}]}, {"chain": "IN_public_allow", "rules": [{"pkts": 1, "bytes": 64, "target": "ACCEPT", "prot": "tcp", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "tcp dpt:22 ctstate NEW,UNTRACKED"}]}, {"chain": "IN_public_deny", "rules": []}, {"chain": "IN_public_log", "rules": []}, {"chain": "OUTPUT_direct", "rules": []}] +[{"chain":"INPUT","default_policy":"ACCEPT","default_packets":0,"default_bytes":0,"rules":[{"pkts":4175,"bytes":1130000,"target":"ACCEPT","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"ctstate RELATED,ESTABLISHED"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"all","opt":null,"in":"lo","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":2383,"bytes":204000,"target":"INPUT_direct","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":2383,"bytes":204000,"target":"INPUT_ZONES_SOURCE","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":2383,"bytes":204000,"target":"INPUT_ZONES","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":0,"bytes":0,"target":"DROP","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"ctstate INVALID"},{"pkts":2382,"bytes":204000,"target":"REJECT","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"reject-with icmp-host-prohibited"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"all","opt":null,"in":"lo","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"ctstate RELATED,ESTABLISHED"},{"pkts":0,"bytes":0,"target":"DROP","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"ctstate INVALID"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"tcp","opt":null,"in":"*","out":"*","source":"15.15.15.0/24","destination":"0.0.0.0/0","options":"tcp dpt:22 ctstate NEW,ESTABLISHED"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"all","opt":null,"in":"lo","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"ctstate RELATED,ESTABLISHED"},{"pkts":0,"bytes":0,"target":"DROP","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"ctstate INVALID"},{"pkts":0,"bytes":0,"target":"DROP","prot":"all","opt":null,"in":"lo","out":"*","source":"15.15.15.51","destination":"0.0.0.0/0"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"tcp","opt":null,"in":"*","out":"*","source":"15.15.15.0/24","destination":"0.0.0.0/0","options":"tcp dpt:22 ctstate NEW,ESTABLISHED"}]},{"chain":"FORWARD","default_policy":"DROP","default_packets":0,"default_bytes":0,"rules":[{"pkts":0,"bytes":0,"target":"DOCKER-ISOLATION","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":0,"bytes":0,"target":"DOCKER","prot":"all","opt":null,"in":"*","out":"docker0","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"all","opt":null,"in":"*","out":"docker0","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"ctstate RELATED,ESTABLISHED"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"all","opt":null,"in":"docker0","out":"!docker0","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"all","opt":null,"in":"docker0","out":"docker0","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"ctstate RELATED,ESTABLISHED"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"all","opt":null,"in":"lo","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":0,"bytes":0,"target":"FORWARD_direct","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":0,"bytes":0,"target":"FORWARD_IN_ZONES_SOURCE","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":0,"bytes":0,"target":"FORWARD_IN_ZONES","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":0,"bytes":0,"target":"FORWARD_OUT_ZONES_SOURCE","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":0,"bytes":0,"target":"FORWARD_OUT_ZONES","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":0,"bytes":0,"target":"DROP","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"ctstate INVALID"},{"pkts":0,"bytes":0,"target":"REJECT","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"reject-with icmp-host-prohibited"}]},{"chain":"OUTPUT","default_policy":"ACCEPT","default_packets":5,"default_bytes":345,"rules":[{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"all","opt":null,"in":"*","out":"lo","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":3419,"bytes":573000,"target":"OUTPUT_direct","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"all","opt":null,"in":"*","out":"lo","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":225,"bytes":101000,"target":"ACCEPT","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"ctstate ESTABLISHED"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"tcp","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"tcp spt:22 ctstate ESTABLISHED"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"all","opt":null,"in":"*","out":"lo","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"ctstate ESTABLISHED"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"tcp","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"tcp spt:22 ctstate ESTABLISHED"}]},{"chain":"DOCKER","rules":[]},{"chain":"DOCKER-ISOLATION","rules":[{"pkts":0,"bytes":0,"target":"RETURN","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"}]},{"chain":"FORWARD_IN_ZONES","rules":[{"pkts":0,"bytes":0,"target":"FWDI_public","prot":"all","opt":null,"in":"ens33","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"[goto] "},{"pkts":0,"bytes":0,"target":"FWDI_public","prot":"all","opt":null,"in":"+","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"[goto] "}]},{"chain":"FORWARD_IN_ZONES_SOURCE","rules":[]},{"chain":"FORWARD_OUT_ZONES","rules":[{"pkts":0,"bytes":0,"target":"FWDO_public","prot":"all","opt":null,"in":"*","out":"ens33","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"[goto] "},{"pkts":0,"bytes":0,"target":"FWDO_public","prot":"all","opt":null,"in":"*","out":"+","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"[goto] "}]},{"chain":"FORWARD_OUT_ZONES_SOURCE","rules":[]},{"chain":"FORWARD_direct","rules":[]},{"chain":"FWDI_public","rules":[{"pkts":0,"bytes":0,"target":"FWDI_public_log","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":0,"bytes":0,"target":"FWDI_public_deny","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":0,"bytes":0,"target":"FWDI_public_allow","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"icmp","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"}]},{"chain":"FWDI_public_allow","rules":[]},{"chain":"FWDI_public_deny","rules":[]},{"chain":"FWDI_public_log","rules":[]},{"chain":"FWDO_public","rules":[{"pkts":0,"bytes":0,"target":"FWDO_public_log","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":0,"bytes":0,"target":"FWDO_public_deny","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":0,"bytes":0,"target":"FWDO_public_allow","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"}]},{"chain":"FWDO_public_allow","rules":[]},{"chain":"FWDO_public_deny","rules":[]},{"chain":"FWDO_public_log","rules":[]},{"chain":"INPUT_ZONES","rules":[{"pkts":2367,"bytes":202000,"target":"IN_public","prot":"all","opt":null,"in":"ens33","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"[goto] "},{"pkts":1,"bytes":330,"target":"IN_public","prot":"all","opt":null,"in":"+","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"[goto] "}]},{"chain":"INPUT_ZONES_SOURCE","rules":[]},{"chain":"INPUT_direct","rules":[]},{"chain":"IN_public","rules":[{"pkts":2383,"bytes":204000,"target":"IN_public_log","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":2383,"bytes":204000,"target":"IN_public_deny","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":2383,"bytes":204000,"target":"IN_public_allow","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"icmp","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"}]},{"chain":"IN_public_allow","rules":[{"pkts":1,"bytes":64,"target":"ACCEPT","prot":"tcp","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"tcp dpt:22 ctstate NEW,UNTRACKED"}]},{"chain":"IN_public_deny","rules":[]},{"chain":"IN_public_log","rules":[]},{"chain":"OUTPUT_direct","rules":[]}] diff --git a/tests/fixtures/centos-7.7/lsblk-allcols.json b/tests/fixtures/centos-7.7/lsblk-allcols.json index 408dfc2c..742ce7bf 100644 --- a/tests/fixtures/centos-7.7/lsblk-allcols.json +++ b/tests/fixtures/centos-7.7/lsblk-allcols.json @@ -1 +1 @@ -[{"name": "sda", "maj_min": "8:0", "rm": false, "size": "20G", "ro": false, "type": "disk", "mountpoint": null, "kname": "sda", "fstype": null, "label": null, "uuid": null, "partlabel": null, "partuuid": null, "ra": 4096, "model": "VMware Virtual S", "serial": null, "state": "running", "owner": "root", "group": "disk", "mode": "brw-rw----", "alignment": 0, "min_io": 512, "opt_io": 0, "phy_sec": 512, "log_sec": 512, "rota": true, "sched": "deadline", "rq_size": 128, "disc_aln": 0, "disc_gran": "0B", "disc_max": "0B", "disc_zero": false, "wsame": "32M", "wwn": null, "rand": true, "pkname": null, "hctl": "0:0:0:0", "tran": "spi", "rev": "1.0", "vendor": "VMware,"}, {"name": "sda1", "maj_min": "8:1", "rm": false, "size": "1G", "ro": false, "type": "part", "mountpoint": "/boot", "kname": "sda1", "fstype": "xfs", "label": null, "uuid": "05d927bb-5875-49e3-ada1-7f46cb31c932", "partlabel": null, "partuuid": null, "ra": 4096, "model": null, "serial": null, "state": null, "owner": "root", "group": "disk", "mode": "brw-rw----", "alignment": 0, "min_io": 512, "opt_io": 0, "phy_sec": 512, "log_sec": 512, "rota": true, "sched": "deadline", "rq_size": 128, "disc_aln": 0, "disc_gran": "0B", "disc_max": "0B", "disc_zero": false, "wsame": "32M", "wwn": null, "rand": true, "pkname": "sda", "hctl": null, "tran": null, "rev": null, "vendor": null}, {"name": "sda2", "maj_min": "8:2", "rm": false, "size": "19G", "ro": false, "type": "part", "mountpoint": null, "kname": "sda2", "fstype": "LVM2_member", "label": null, "uuid": "3klkIj-w1qk-DkJi-0XBJ-y3o7-i2Ac-vHqWBM", "partlabel": null, "partuuid": null, "ra": 4096, "model": null, "serial": null, "state": null, "owner": "root", "group": "disk", "mode": "brw-rw----", "alignment": 0, "min_io": 512, "opt_io": 0, "phy_sec": 512, "log_sec": 512, "rota": true, "sched": "deadline", "rq_size": 128, "disc_aln": 0, "disc_gran": "0B", "disc_max": "0B", "disc_zero": false, "wsame": "32M", "wwn": null, "rand": true, "pkname": "sda", "hctl": null, "tran": null, "rev": null, "vendor": null}, {"name": "centos-root", "maj_min": "253:0", "rm": false, "size": "17G", "ro": false, "type": "lvm", "mountpoint": "/", "kname": "dm-0", "fstype": "xfs", "label": null, "uuid": "07d718ef-950c-4e5b-98e0-42a1147b77d9", "partlabel": null, "partuuid": null, "ra": 4096, "model": null, "serial": null, "state": "running", "owner": "root", "group": "disk", "mode": "brw-rw----", "alignment": 0, "min_io": 512, "opt_io": 0, "phy_sec": 512, "log_sec": 512, "rota": true, "sched": null, "rq_size": 128, "disc_aln": 0, "disc_gran": "0B", "disc_max": "0B", "disc_zero": false, "wsame": "32M", "wwn": null, "rand": false, "pkname": "sda2", "hctl": null, "tran": null, "rev": null, "vendor": null}, {"name": "centos-swap", "maj_min": "253:1", "rm": false, "size": "2G", "ro": false, "type": "lvm", "mountpoint": "[SWAP]", "kname": "dm-1", "fstype": "swap", "label": null, "uuid": "615eb89d-bcbf-46ad-80e3-c483ef5c931f", "partlabel": null, "partuuid": null, "ra": 4096, "model": null, "serial": null, "state": "running", "owner": "root", "group": "disk", "mode": "brw-rw----", "alignment": 0, "min_io": 512, "opt_io": 0, "phy_sec": 512, "log_sec": 512, "rota": true, "sched": null, "rq_size": 128, "disc_aln": 0, "disc_gran": "0B", "disc_max": "0B", "disc_zero": false, "wsame": "32M", "wwn": null, "rand": false, "pkname": "sda2", "hctl": null, "tran": null, "rev": null, "vendor": null}, {"name": "sr0", "maj_min": "11:0", "rm": true, "size": "1024M", "ro": false, "type": "rom", "mountpoint": null, "kname": "sr0", "fstype": null, "label": null, "uuid": null, "partlabel": null, "partuuid": null, "ra": 128, "model": "VMware IDE CDR10", "serial": "10000000000000000001", "state": "running", "owner": "root", "group": "cdrom", "mode": "brw-rw----", "alignment": 0, "min_io": 512, "opt_io": 0, "phy_sec": 512, "log_sec": 512, "rota": true, "sched": "deadline", "rq_size": 128, "disc_aln": 0, "disc_gran": "0B", "disc_max": "0B", "disc_zero": false, "wsame": "0B", "wwn": null, "rand": true, "pkname": null, "hctl": "2:0:0:0", "tran": "ata", "rev": "1.00", "vendor": "NECVMWar"}] +[{"name":"sda","maj_min":"8:0","rm":false,"size":"20G","ro":false,"type":"disk","mountpoint":null,"kname":"sda","fstype":null,"label":null,"uuid":null,"partlabel":null,"partuuid":null,"ra":4096,"model":"VMware Virtual S","serial":null,"state":"running","owner":"root","group":"disk","mode":"brw-rw----","alignment":0,"min_io":512,"opt_io":0,"phy_sec":512,"log_sec":512,"rota":true,"sched":"deadline","rq_size":128,"disc_aln":0,"disc_gran":"0B","disc_max":"0B","disc_zero":false,"wsame":"32M","wwn":null,"rand":true,"pkname":null,"hctl":"0:0:0:0","tran":"spi","rev":"1.0","vendor":"VMware,","size_bytes":21474836480,"disc_gran_bytes":0,"disc_max_bytes":0,"wsame_bytes":33554432},{"name":"sda1","maj_min":"8:1","rm":false,"size":"1G","ro":false,"type":"part","mountpoint":"/boot","kname":"sda1","fstype":"xfs","label":null,"uuid":"05d927bb-5875-49e3-ada1-7f46cb31c932","partlabel":null,"partuuid":null,"ra":4096,"model":null,"serial":null,"state":null,"owner":"root","group":"disk","mode":"brw-rw----","alignment":0,"min_io":512,"opt_io":0,"phy_sec":512,"log_sec":512,"rota":true,"sched":"deadline","rq_size":128,"disc_aln":0,"disc_gran":"0B","disc_max":"0B","disc_zero":false,"wsame":"32M","wwn":null,"rand":true,"pkname":"sda","hctl":null,"tran":null,"rev":null,"vendor":null,"size_bytes":1073741824,"disc_gran_bytes":0,"disc_max_bytes":0,"wsame_bytes":33554432},{"name":"sda2","maj_min":"8:2","rm":false,"size":"19G","ro":false,"type":"part","mountpoint":null,"kname":"sda2","fstype":"LVM2_member","label":null,"uuid":"3klkIj-w1qk-DkJi-0XBJ-y3o7-i2Ac-vHqWBM","partlabel":null,"partuuid":null,"ra":4096,"model":null,"serial":null,"state":null,"owner":"root","group":"disk","mode":"brw-rw----","alignment":0,"min_io":512,"opt_io":0,"phy_sec":512,"log_sec":512,"rota":true,"sched":"deadline","rq_size":128,"disc_aln":0,"disc_gran":"0B","disc_max":"0B","disc_zero":false,"wsame":"32M","wwn":null,"rand":true,"pkname":"sda","hctl":null,"tran":null,"rev":null,"vendor":null,"size_bytes":20401094656,"disc_gran_bytes":0,"disc_max_bytes":0,"wsame_bytes":33554432},{"name":"centos-root","maj_min":"253:0","rm":false,"size":"17G","ro":false,"type":"lvm","mountpoint":"/","kname":"dm-0","fstype":"xfs","label":null,"uuid":"07d718ef-950c-4e5b-98e0-42a1147b77d9","partlabel":null,"partuuid":null,"ra":4096,"model":null,"serial":null,"state":"running","owner":"root","group":"disk","mode":"brw-rw----","alignment":0,"min_io":512,"opt_io":0,"phy_sec":512,"log_sec":512,"rota":true,"sched":null,"rq_size":128,"disc_aln":0,"disc_gran":"0B","disc_max":"0B","disc_zero":false,"wsame":"32M","wwn":null,"rand":false,"pkname":"sda2","hctl":null,"tran":null,"rev":null,"vendor":null,"size_bytes":18253611008,"disc_gran_bytes":0,"disc_max_bytes":0,"wsame_bytes":33554432},{"name":"centos-swap","maj_min":"253:1","rm":false,"size":"2G","ro":false,"type":"lvm","mountpoint":"[SWAP]","kname":"dm-1","fstype":"swap","label":null,"uuid":"615eb89d-bcbf-46ad-80e3-c483ef5c931f","partlabel":null,"partuuid":null,"ra":4096,"model":null,"serial":null,"state":"running","owner":"root","group":"disk","mode":"brw-rw----","alignment":0,"min_io":512,"opt_io":0,"phy_sec":512,"log_sec":512,"rota":true,"sched":null,"rq_size":128,"disc_aln":0,"disc_gran":"0B","disc_max":"0B","disc_zero":false,"wsame":"32M","wwn":null,"rand":false,"pkname":"sda2","hctl":null,"tran":null,"rev":null,"vendor":null,"size_bytes":2147483648,"disc_gran_bytes":0,"disc_max_bytes":0,"wsame_bytes":33554432},{"name":"sr0","maj_min":"11:0","rm":true,"size":"1024M","ro":false,"type":"rom","mountpoint":null,"kname":"sr0","fstype":null,"label":null,"uuid":null,"partlabel":null,"partuuid":null,"ra":128,"model":"VMware IDE CDR10","serial":"10000000000000000001","state":"running","owner":"root","group":"cdrom","mode":"brw-rw----","alignment":0,"min_io":512,"opt_io":0,"phy_sec":512,"log_sec":512,"rota":true,"sched":"deadline","rq_size":128,"disc_aln":0,"disc_gran":"0B","disc_max":"0B","disc_zero":false,"wsame":"0B","wwn":null,"rand":true,"pkname":null,"hctl":"2:0:0:0","tran":"ata","rev":"1.00","vendor":"NECVMWar","size_bytes":1073741824,"disc_gran_bytes":0,"disc_max_bytes":0,"wsame_bytes":0}] diff --git a/tests/fixtures/centos-7.7/lsblk.json b/tests/fixtures/centos-7.7/lsblk.json index 43c3b0ae..c5cdb169 100644 --- a/tests/fixtures/centos-7.7/lsblk.json +++ b/tests/fixtures/centos-7.7/lsblk.json @@ -1 +1 @@ -[{"name": "sda", "maj_min": "8:0", "rm": false, "size": "20G", "ro": false, "type": "disk", "mountpoint": null}, {"name": "sda1", "maj_min": "8:1", "rm": false, "size": "1G", "ro": false, "type": "part", "mountpoint": "/boot"}, {"name": "sda2", "maj_min": "8:2", "rm": false, "size": "19G", "ro": false, "type": "part", "mountpoint": null}, {"name": "centos-root", "maj_min": "253:0", "rm": false, "size": "17G", "ro": false, "type": "lvm", "mountpoint": "/"}, {"name": "centos-swap", "maj_min": "253:1", "rm": false, "size": "2G", "ro": false, "type": "lvm", "mountpoint": "[SWAP]"}, {"name": "sr0", "maj_min": "11:0", "rm": true, "size": "1024M", "ro": false, "type": "rom", "mountpoint": null}] +[{"name":"sda","maj_min":"8:0","rm":false,"size":"20G","ro":false,"type":"disk","mountpoint":null,"size_bytes":21474836480},{"name":"sda1","maj_min":"8:1","rm":false,"size":"1G","ro":false,"type":"part","mountpoint":"/boot","size_bytes":1073741824},{"name":"sda2","maj_min":"8:2","rm":false,"size":"19G","ro":false,"type":"part","mountpoint":null,"size_bytes":20401094656},{"name":"centos-root","maj_min":"253:0","rm":false,"size":"17G","ro":false,"type":"lvm","mountpoint":"/","size_bytes":18253611008},{"name":"centos-swap","maj_min":"253:1","rm":false,"size":"2G","ro":false,"type":"lvm","mountpoint":"[SWAP]","size_bytes":2147483648},{"name":"sr0","maj_min":"11:0","rm":true,"size":"1024M","ro":false,"type":"rom","mountpoint":null,"size_bytes":1073741824}] diff --git a/tests/fixtures/generic/bluetoothctl_controller_2.out b/tests/fixtures/generic/bluetoothctl_controller_2.out new file mode 100644 index 00000000..1024227f --- /dev/null +++ b/tests/fixtures/generic/bluetoothctl_controller_2.out @@ -0,0 +1,20 @@ +Controller CC:52:AF:17:6A:E4 (public) + Manufacturer: 0x000f (15) + Version: 0x05 (5) + Name: starbase + Alias: starbase + Class: 0x006c010c (7078156) + Powered: yes + PowerState: on + Discoverable: no + DiscoverableTimeout: 0x000000b4 (180) + Pairable: no + UUID: Handsfree (0000111e-0000-1000-8000-00805f9b34fb) + UUID: Audio Source (0000110a-0000-1000-8000-00805f9b34fb) + UUID: Audio Sink (0000110b-0000-1000-8000-00805f9b34fb) + UUID: PnP Information (00001200-0000-1000-8000-00805f9b34fb) + UUID: A/V Remote Control Target (0000110c-0000-1000-8000-00805f9b34fb) + UUID: A/V Remote Control (0000110e-0000-1000-8000-00805f9b34fb) + UUID: Handsfree Audio Gateway (0000111f-0000-1000-8000-00805f9b34fb) + Modalias: usb:v1D6Bp0246d054F + Discovering: no diff --git a/tests/fixtures/generic/mount-parens-in-filesystem.json b/tests/fixtures/generic/mount-parens-in-filesystem.json new file mode 100644 index 00000000..2c6cfbbe --- /dev/null +++ b/tests/fixtures/generic/mount-parens-in-filesystem.json @@ -0,0 +1 @@ +[{"filesystem":"/dev/disk3s1s1","mount_point":"/","options":["apfs","sealed","local","read-only","journaled"]},{"filesystem":"devfs","mount_point":"/dev","options":["devfs","local","nobrowse"]},{"filesystem":"/dev/disk3s6","mount_point":"/System/Volumes/VM","options":["apfs","local","noexec","journaled","noatime","nobrowse"]},{"filesystem":"/dev/disk3s2","mount_point":"/System/Volumes/Preboot","options":["apfs","local","journaled","nobrowse"]},{"filesystem":"/dev/disk3s4","mount_point":"/System/Volumes/Update","options":["apfs","local","journaled","nobrowse"]},{"filesystem":"/dev/disk2s2","mount_point":"/System/Volumes/xarts","options":["apfs","local","noexec","journaled","noatime","nobrowse"]},{"filesystem":"/dev/disk2s1","mount_point":"/System/Volumes/iSCPreboot","options":["apfs","local","journaled","nobrowse"]},{"filesystem":"/dev/disk2s3","mount_point":"/System/Volumes/Hardware","options":["apfs","local","journaled","nobrowse"]},{"filesystem":"/dev/disk3s5","mount_point":"/System/Volumes/Data","options":["apfs","local","journaled","nobrowse","protect","root data"]},{"filesystem":"map auto_home","mount_point":"/System/Volumes/Data/home","options":["autofs","automounted","nobrowse"]},{"filesystem":"MN - mydomain.com (ftp.mydomain.com):/","mount_point":"/Users/muescha/Library/Application Support/Mountain Duck/Volumes.noindex/MN - mydomain.com.localized","options":["nfs","asynchronous","nodev","nosuid","noowners","noatime","mounted by muescha"]},{"filesystem":"/dev/disk5s1","mount_point":"/Library/Developer/CoreSimulator/Volumes/iOS_21F79","options":["apfs","local","nodev","nosuid","read-only","journaled","noowners","noatime","nobrowse"]},{"filesystem":"/dev/disk7s1","mount_point":"/Library/Developer/CoreSimulator/Cryptex/Images/bundle/SimRuntimeBundle-A3CF7B3B-543B-4D71-BA03-12F939EA0B4D","options":["apfs","local","nodev","nosuid","read-only","journaled","noowners","noatime","nobrowse"]},{"filesystem":"/dev/disk9s1","mount_point":"/Library/Developer/CoreSimulator/Volumes/iOS_22C150","options":["apfs","sealed","local","nodev","nosuid","read-only","journaled","noowners","noatime","nobrowse"]}] diff --git a/tests/fixtures/generic/mount-parens-in-filesystem.out b/tests/fixtures/generic/mount-parens-in-filesystem.out new file mode 100644 index 00000000..f7d37c03 --- /dev/null +++ b/tests/fixtures/generic/mount-parens-in-filesystem.out @@ -0,0 +1,14 @@ +/dev/disk3s1s1 on / (apfs, sealed, local, read-only, journaled) +devfs on /dev (devfs, local, nobrowse) +/dev/disk3s6 on /System/Volumes/VM (apfs, local, noexec, journaled, noatime, nobrowse) +/dev/disk3s2 on /System/Volumes/Preboot (apfs, local, journaled, nobrowse) +/dev/disk3s4 on /System/Volumes/Update (apfs, local, journaled, nobrowse) +/dev/disk2s2 on /System/Volumes/xarts (apfs, local, noexec, journaled, noatime, nobrowse) +/dev/disk2s1 on /System/Volumes/iSCPreboot (apfs, local, journaled, nobrowse) +/dev/disk2s3 on /System/Volumes/Hardware (apfs, local, journaled, nobrowse) +/dev/disk3s5 on /System/Volumes/Data (apfs, local, journaled, nobrowse, protect, root data) +map auto_home on /System/Volumes/Data/home (autofs, automounted, nobrowse) +MN - mydomain.com (ftp.mydomain.com):/ on /Users/muescha/Library/Application Support/Mountain Duck/Volumes.noindex/MN - mydomain.com.localized (nfs, asynchronous, nodev, nosuid, noowners, noatime, mounted by muescha) +/dev/disk5s1 on /Library/Developer/CoreSimulator/Volumes/iOS_21F79 (apfs, local, nodev, nosuid, read-only, journaled, noowners, noatime, nobrowse) +/dev/disk7s1 on /Library/Developer/CoreSimulator/Cryptex/Images/bundle/SimRuntimeBundle-A3CF7B3B-543B-4D71-BA03-12F939EA0B4D (apfs, local, nodev, nosuid, read-only, journaled, noowners, noatime, nobrowse) +/dev/disk9s1 on /Library/Developer/CoreSimulator/Volumes/iOS_22C150 (apfs, sealed, local, nodev, nosuid, read-only, journaled, noowners, noatime, nobrowse) diff --git a/tests/fixtures/generic/x509-cert-bad-email2.der b/tests/fixtures/generic/x509-cert-bad-email2.der new file mode 100644 index 00000000..20ce02b5 Binary files /dev/null and b/tests/fixtures/generic/x509-cert-bad-email2.der differ diff --git a/tests/fixtures/generic/x509-cert-bad-email2.json b/tests/fixtures/generic/x509-cert-bad-email2.json new file mode 100644 index 00000000..6743f076 --- /dev/null +++ b/tests/fixtures/generic/x509-cert-bad-email2.json @@ -0,0 +1 @@ +[{"tbs_certificate":{"version":"v3","serial_number":"37:12:43:a3:c9:eb:75:b7:61:6f:39:5f:0f:4d:a9:d4:6a:67:61:c2","signature":{"algorithm":"sha256_ecdsa","parameters":null},"issuer":{"common_name":"idna issues Inc."},"validity":{"not_before":1744299375,"not_after":2059659375,"not_before_iso":"2025-04-10T15:36:15+00:00","not_after_iso":"2035-04-08T15:36:15+00:00"},"subject":{"common_name":"idna issues Inc."},"subject_public_key_info":{"algorithm":{"algorithm":"ec","parameters":"secp256r1"},"public_key":"04:c4:e7:a0:b8:d0:5a:d3:77:86:e9:b2:b4:0d:4c:4f:52:25:0b:53:5b:21:5e:f1:50:1e:4f:6c:f4:8f:44:03:50:c2:ee:0e:61:2b:56:09:25:5c:4c:17:2a:78:cd:d2:ff:f5:8f:0e:68:eb:c9:4b:8a:18:0d:62:8d:9b:46:5f:71"},"issuer_unique_id":null,"subject_unique_id":null,"extensions":[{"extn_id":"subject_alt_name","critical":false,"extn_value":["sesam@xn--strae-oqa.de"]}],"serial_number_str":"314401798066465365584221074488388179068992315842"},"signature_algorithm":{"algorithm":"sha256_ecdsa","parameters":null},"signature_value":"30:46:02:21:00:9c:3b:38:eb:d6:52:e4:49:4b:4c:0a:19:04:56:45:66:31:4f:fd:c0:8d:ec:6c:c7:61:61:81:40:08:55:64:c2:02:21:00:f9:a1:38:ea:5a:f0:c1:2e:7c:c1:92:bd:f8:20:77:dd:50:63:5b:6d:7e:8a:35:28:97:bf:30:b0:db:d0:85:f1"}] diff --git a/tests/fixtures/ubuntu-18.04/iptables-filter-nv.json b/tests/fixtures/ubuntu-18.04/iptables-filter-nv.json index 6793ed7c..d8d228a5 100644 --- a/tests/fixtures/ubuntu-18.04/iptables-filter-nv.json +++ b/tests/fixtures/ubuntu-18.04/iptables-filter-nv.json @@ -1 +1 @@ -[{"chain": "INPUT", "rules": [{"pkts": 66, "bytes": 6034, "target": "ACCEPT", "prot": "all", "opt": null, "in": "lo", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 1137, "bytes": 318000, "target": "ACCEPT", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "ctstate RELATED,ESTABLISHED"}, {"pkts": 0, "bytes": 0, "target": "DROP", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "ctstate INVALID"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "tcp", "opt": null, "in": "*", "out": "*", "source": "15.15.15.0/24", "destination": "0.0.0.0/0", "options": "tcp dpt:22 ctstate NEW,ESTABLISHED"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "all", "opt": null, "in": "lo", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "ctstate RELATED,ESTABLISHED"}, {"pkts": 0, "bytes": 0, "target": "DROP", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "ctstate INVALID"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "tcp", "opt": null, "in": "*", "out": "*", "source": "15.15.15.0/24", "destination": "0.0.0.0/0", "options": "tcp dpt:22 ctstate NEW,ESTABLISHED"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "all", "opt": null, "in": "lo", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "ctstate RELATED,ESTABLISHED"}, {"pkts": 0, "bytes": 0, "target": "DROP", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "ctstate INVALID"}, {"pkts": 0, "bytes": 0, "target": "DROP", "prot": "all", "opt": null, "in": "lo", "out": "*", "source": "15.15.15.51", "destination": "0.0.0.0/0"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "tcp", "opt": null, "in": "*", "out": "*", "source": "15.15.15.0/24", "destination": "0.0.0.0/0", "options": "tcp dpt:22 ctstate NEW,ESTABLISHED"}]}, {"chain": "FORWARD", "rules": []}, {"chain": "OUTPUT", "rules": [{"pkts": 66, "bytes": 6034, "target": "ACCEPT", "prot": "all", "opt": null, "in": "*", "out": "lo", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 889, "bytes": 158000, "target": "ACCEPT", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "ctstate ESTABLISHED"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "tcp", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "tcp spt:22 ctstate ESTABLISHED"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "all", "opt": null, "in": "*", "out": "lo", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "ctstate ESTABLISHED"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "tcp", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "tcp spt:22 ctstate ESTABLISHED"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "all", "opt": null, "in": "*", "out": "lo", "source": "0.0.0.0/0", "destination": "0.0.0.0/0"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "all", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "ctstate ESTABLISHED"}, {"pkts": 0, "bytes": 0, "target": "ACCEPT", "prot": "tcp", "opt": null, "in": "*", "out": "*", "source": "0.0.0.0/0", "destination": "0.0.0.0/0", "options": "tcp spt:22 ctstate ESTABLISHED"}]}] +[{"chain":"INPUT","default_policy":"ACCEPT","default_packets":0,"default_bytes":0,"rules":[{"pkts":66,"bytes":6034,"target":"ACCEPT","prot":"all","opt":null,"in":"lo","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":1137,"bytes":318000,"target":"ACCEPT","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"ctstate RELATED,ESTABLISHED"},{"pkts":0,"bytes":0,"target":"DROP","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"ctstate INVALID"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"tcp","opt":null,"in":"*","out":"*","source":"15.15.15.0/24","destination":"0.0.0.0/0","options":"tcp dpt:22 ctstate NEW,ESTABLISHED"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"all","opt":null,"in":"lo","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"ctstate RELATED,ESTABLISHED"},{"pkts":0,"bytes":0,"target":"DROP","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"ctstate INVALID"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"tcp","opt":null,"in":"*","out":"*","source":"15.15.15.0/24","destination":"0.0.0.0/0","options":"tcp dpt:22 ctstate NEW,ESTABLISHED"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"all","opt":null,"in":"lo","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"ctstate RELATED,ESTABLISHED"},{"pkts":0,"bytes":0,"target":"DROP","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"ctstate INVALID"},{"pkts":0,"bytes":0,"target":"DROP","prot":"all","opt":null,"in":"lo","out":"*","source":"15.15.15.51","destination":"0.0.0.0/0"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"tcp","opt":null,"in":"*","out":"*","source":"15.15.15.0/24","destination":"0.0.0.0/0","options":"tcp dpt:22 ctstate NEW,ESTABLISHED"}]},{"chain":"FORWARD","default_policy":"ACCEPT","default_packets":0,"default_bytes":0,"rules":[]},{"chain":"OUTPUT","default_policy":"ACCEPT","default_packets":4,"default_bytes":277,"rules":[{"pkts":66,"bytes":6034,"target":"ACCEPT","prot":"all","opt":null,"in":"*","out":"lo","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":889,"bytes":158000,"target":"ACCEPT","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"ctstate ESTABLISHED"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"tcp","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"tcp spt:22 ctstate ESTABLISHED"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"all","opt":null,"in":"*","out":"lo","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"ctstate ESTABLISHED"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"tcp","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"tcp spt:22 ctstate ESTABLISHED"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"all","opt":null,"in":"*","out":"lo","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"all","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"ctstate ESTABLISHED"},{"pkts":0,"bytes":0,"target":"ACCEPT","prot":"tcp","opt":null,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"tcp spt:22 ctstate ESTABLISHED"}]}] diff --git a/tests/fixtures/ubuntu-18.04/lsblk-allcols.json b/tests/fixtures/ubuntu-18.04/lsblk-allcols.json index ff3d82ca..359d3d47 100644 --- a/tests/fixtures/ubuntu-18.04/lsblk-allcols.json +++ b/tests/fixtures/ubuntu-18.04/lsblk-allcols.json @@ -1 +1 @@ -[{"name": "fd0", "maj_min": "2:0", "rm": true, "size": "1.4M", "ro": false, "type": "disk", "mountpoint": null, "kname": "fd0", "fstype": null, "label": null, "uuid": null, "partlabel": null, "partuuid": null, "ra": 128, "model": null, "serial": null, "state": null, "owner": "root", "group": "disk", "mode": "brw-rw----", "alignment": 0, "min_io": 512, "opt_io": 0, "phy_sec": 512, "log_sec": 512, "rota": true, "sched": "cfq", "rq_size": 128, "disc_aln": 0, "disc_gran": "0B", "disc_max": "0B", "disc_zero": false, "wsame": "0B", "wwn": null, "rand": true, "pkname": null, "hctl": null, "tran": null, "rev": null, "vendor": null}, {"name": "loop0", "maj_min": "7:0", "rm": false, "size": "54.5M", "ro": true, "type": "loop", "mountpoint": "/snap/core18/1223", "kname": "loop0", "fstype": "squashfs", "label": null, "uuid": null, "partlabel": null, "partuuid": null, "ra": 128, "model": null, "serial": null, "state": null, "owner": "root", "group": "disk", "mode": "brw-rw----", "alignment": 0, "min_io": 512, "opt_io": 0, "phy_sec": 512, "log_sec": 512, "rota": true, "sched": "none", "rq_size": 128, "disc_aln": 0, "disc_gran": "4K", "disc_max": "4G", "disc_zero": false, "wsame": "0B", "wwn": null, "rand": false, "pkname": null, "hctl": null, "tran": null, "rev": null, "vendor": null}, {"name": "loop1", "maj_min": "7:1", "rm": false, "size": "89.1M", "ro": true, "type": "loop", "mountpoint": "/snap/core/7917", "kname": "loop1", "fstype": "squashfs", "label": null, "uuid": null, "partlabel": null, "partuuid": null, "ra": 128, "model": null, "serial": null, "state": null, "owner": "root", "group": "disk", "mode": "brw-rw----", "alignment": 0, "min_io": 512, "opt_io": 0, "phy_sec": 512, "log_sec": 512, "rota": true, "sched": "none", "rq_size": 128, "disc_aln": 0, "disc_gran": "4K", "disc_max": "4G", "disc_zero": false, "wsame": "0B", "wwn": null, "rand": false, "pkname": null, "hctl": null, "tran": null, "rev": null, "vendor": null}, {"name": "loop2", "maj_min": "7:2", "rm": false, "size": "11M", "ro": true, "type": "loop", "mountpoint": "/snap/slcli/383", "kname": "loop2", "fstype": "squashfs", "label": null, "uuid": null, "partlabel": null, "partuuid": null, "ra": 128, "model": null, "serial": null, "state": null, "owner": "root", "group": "disk", "mode": "brw-rw----", "alignment": 0, "min_io": 512, "opt_io": 0, "phy_sec": 512, "log_sec": 512, "rota": true, "sched": "none", "rq_size": 128, "disc_aln": 0, "disc_gran": "4K", "disc_max": "4G", "disc_zero": false, "wsame": "0B", "wwn": null, "rand": false, "pkname": null, "hctl": null, "tran": null, "rev": null, "vendor": null}, {"name": "loop3", "maj_min": "7:3", "rm": false, "size": "8.6M", "ro": true, "type": "loop", "mountpoint": "/snap/doctl/215", "kname": "loop3", "fstype": "squashfs", "label": null, "uuid": null, "partlabel": null, "partuuid": null, "ra": 128, "model": null, "serial": null, "state": null, "owner": "root", "group": "disk", "mode": "brw-rw----", "alignment": 0, "min_io": 512, "opt_io": 0, "phy_sec": 512, "log_sec": 512, "rota": true, "sched": "none", "rq_size": 128, "disc_aln": 0, "disc_gran": "4K", "disc_max": "4G", "disc_zero": false, "wsame": "0B", "wwn": null, "rand": false, "pkname": null, "hctl": null, "tran": null, "rev": null, "vendor": null}, {"name": "loop4", "maj_min": "7:4", "rm": false, "size": "89.1M", "ro": true, "type": "loop", "mountpoint": "/snap/core/8039", "kname": "loop4", "fstype": "squashfs", "label": null, "uuid": null, "partlabel": null, "partuuid": null, "ra": 128, "model": null, "serial": null, "state": null, "owner": "root", "group": "disk", "mode": "brw-rw----", "alignment": 0, "min_io": 512, "opt_io": 0, "phy_sec": 512, "log_sec": 512, "rota": true, "sched": "none", "rq_size": 128, "disc_aln": 0, "disc_gran": "4K", "disc_max": "4G", "disc_zero": false, "wsame": "0B", "wwn": null, "rand": false, "pkname": null, "hctl": null, "tran": null, "rev": null, "vendor": null}, {"name": "loop5", "maj_min": "7:5", "rm": false, "size": "67M", "ro": true, "type": "loop", "mountpoint": "/snap/google-cloud-sdk/106", "kname": "loop5", "fstype": "squashfs", "label": null, "uuid": null, "partlabel": null, "partuuid": null, "ra": 128, "model": null, "serial": null, "state": null, "owner": "root", "group": "disk", "mode": "brw-rw----", "alignment": 0, "min_io": 512, "opt_io": 0, "phy_sec": 512, "log_sec": 512, "rota": true, "sched": "none", "rq_size": 128, "disc_aln": 0, "disc_gran": "4K", "disc_max": "4G", "disc_zero": false, "wsame": "0B", "wwn": null, "rand": false, "pkname": null, "hctl": null, "tran": null, "rev": null, "vendor": null}, {"name": "loop6", "maj_min": "7:6", "rm": false, "size": "66.8M", "ro": true, "type": "loop", "mountpoint": "/snap/google-cloud-sdk/105", "kname": "loop6", "fstype": "squashfs", "label": null, "uuid": null, "partlabel": null, "partuuid": null, "ra": 128, "model": null, "serial": null, "state": null, "owner": "root", "group": "disk", "mode": "brw-rw----", "alignment": 0, "min_io": 512, "opt_io": 0, "phy_sec": 512, "log_sec": 512, "rota": true, "sched": "none", "rq_size": 128, "disc_aln": 0, "disc_gran": "4K", "disc_max": "4G", "disc_zero": false, "wsame": "0B", "wwn": null, "rand": false, "pkname": null, "hctl": null, "tran": null, "rev": null, "vendor": null}, {"name": "loop7", "maj_min": "7:7", "rm": false, "size": "3.2M", "ro": true, "type": "loop", "mountpoint": "/snap/stress-ng/1046", "kname": "loop7", "fstype": "squashfs", "label": null, "uuid": null, "partlabel": null, "partuuid": null, "ra": 128, "model": null, "serial": null, "state": null, "owner": "root", "group": "disk", "mode": "brw-rw----", "alignment": 0, "min_io": 512, "opt_io": 0, "phy_sec": 512, "log_sec": 512, "rota": true, "sched": "none", "rq_size": 128, "disc_aln": 0, "disc_gran": "4K", "disc_max": "4G", "disc_zero": false, "wsame": "0B", "wwn": null, "rand": false, "pkname": null, "hctl": null, "tran": null, "rev": null, "vendor": null}, {"name": "loop8", "maj_min": "7:8", "rm": false, "size": "8.7M", "ro": true, "type": "loop", "mountpoint": "/snap/doctl/222", "kname": "loop8", "fstype": "squashfs", "label": null, "uuid": null, "partlabel": null, "partuuid": null, "ra": 128, "model": null, "serial": null, "state": null, "owner": "root", "group": "disk", "mode": "brw-rw----", "alignment": 0, "min_io": 512, "opt_io": 0, "phy_sec": 512, "log_sec": 512, "rota": true, "sched": "none", "rq_size": 128, "disc_aln": 0, "disc_gran": "4K", "disc_max": "4G", "disc_zero": false, "wsame": "0B", "wwn": null, "rand": false, "pkname": null, "hctl": null, "tran": null, "rev": null, "vendor": null}, {"name": "loop9", "maj_min": "7:9", "rm": false, "size": "54.5M", "ro": true, "type": "loop", "mountpoint": "/snap/core18/1265", "kname": "loop9", "fstype": "squashfs", "label": null, "uuid": null, "partlabel": null, "partuuid": null, "ra": 128, "model": null, "serial": null, "state": null, "owner": "root", "group": "disk", "mode": "brw-rw----", "alignment": 0, "min_io": 512, "opt_io": 0, "phy_sec": 512, "log_sec": 512, "rota": true, "sched": "none", "rq_size": 128, "disc_aln": 0, "disc_gran": "4K", "disc_max": "4G", "disc_zero": false, "wsame": "0B", "wwn": null, "rand": false, "pkname": null, "hctl": null, "tran": null, "rev": null, "vendor": null}, {"name": "loop10", "maj_min": "7:10", "rm": false, "size": "3.2M", "ro": true, "type": "loop", "mountpoint": "/snap/stress-ng/1076", "kname": "loop10", "fstype": "squashfs", "label": null, "uuid": null, "partlabel": null, "partuuid": null, "ra": 128, "model": null, "serial": null, "state": null, "owner": "root", "group": "disk", "mode": "brw-rw----", "alignment": 0, "min_io": 512, "opt_io": 0, "phy_sec": 512, "log_sec": 512, "rota": true, "sched": "none", "rq_size": 128, "disc_aln": 0, "disc_gran": "4K", "disc_max": "4G", "disc_zero": false, "wsame": "0B", "wwn": null, "rand": false, "pkname": null, "hctl": null, "tran": null, "rev": null, "vendor": null}, {"name": "sda", "maj_min": "8:0", "rm": false, "size": "20G", "ro": false, "type": "disk", "mountpoint": null, "kname": "sda", "fstype": null, "label": null, "uuid": null, "partlabel": null, "partuuid": null, "ra": 128, "model": "VMware Virtual S", "serial": null, "state": "running", "owner": "root", "group": "disk", "mode": "brw-rw----", "alignment": 0, "min_io": 512, "opt_io": 0, "phy_sec": 512, "log_sec": 512, "rota": true, "sched": "cfq", "rq_size": 128, "disc_aln": 0, "disc_gran": "0B", "disc_max": "0B", "disc_zero": false, "wsame": "0B", "wwn": null, "rand": true, "pkname": null, "hctl": "32:0:0:0", "tran": "spi", "rev": "1.0", "vendor": "VMware,"}, {"name": "sda1", "maj_min": "8:1", "rm": false, "size": "1M", "ro": false, "type": "part", "mountpoint": null, "kname": "sda1", "fstype": null, "label": null, "uuid": null, "partlabel": null, "partuuid": "e0614271-c211-4324-a5bc-8e6bcb66da43", "ra": 128, "model": null, "serial": null, "state": null, "owner": "root", "group": "disk", "mode": "brw-rw----", "alignment": 0, "min_io": 512, "opt_io": 0, "phy_sec": 512, "log_sec": 512, "rota": true, "sched": "cfq", "rq_size": 128, "disc_aln": 0, "disc_gran": "0B", "disc_max": "0B", "disc_zero": false, "wsame": "0B", "wwn": null, "rand": true, "pkname": "sda", "hctl": null, "tran": null, "rev": null, "vendor": null}, {"name": "sda2", "maj_min": "8:2", "rm": false, "size": "20G", "ro": false, "type": "part", "mountpoint": "/", "kname": "sda2", "fstype": "ext4", "label": null, "uuid": "011527a0-c72a-4c00-a50e-ee90da26b6e2", "partlabel": null, "partuuid": "744589e8-5711-4750-9984-c34d66f93879", "ra": 128, "model": null, "serial": null, "state": null, "owner": "root", "group": "disk", "mode": "brw-rw----", "alignment": 0, "min_io": 512, "opt_io": 0, "phy_sec": 512, "log_sec": 512, "rota": true, "sched": "cfq", "rq_size": 128, "disc_aln": 0, "disc_gran": "0B", "disc_max": "0B", "disc_zero": false, "wsame": "0B", "wwn": null, "rand": true, "pkname": "sda", "hctl": null, "tran": null, "rev": null, "vendor": null}, {"name": "sr0", "maj_min": "11:0", "rm": true, "size": "64.8M", "ro": false, "type": "rom", "mountpoint": null, "kname": "sr0", "fstype": "iso9660", "label": "CDROM", "uuid": "2019-08-12-10-17-03-63", "partlabel": null, "partuuid": null, "ra": 128, "model": "VMware SATA CD00", "serial": "00000000000000000001", "state": "running", "owner": "root", "group": "cdrom", "mode": "brw-rw----", "alignment": 0, "min_io": 2048, "opt_io": 0, "phy_sec": 2048, "log_sec": 2048, "rota": true, "sched": "cfq", "rq_size": 128, "disc_aln": 0, "disc_gran": "0B", "disc_max": "0B", "disc_zero": false, "wsame": "0B", "wwn": null, "rand": true, "pkname": null, "hctl": "2:0:0:0", "tran": "sata", "rev": "1.00", "vendor": "NECVMWar"}, {"name": "sr1", "maj_min": "11:1", "rm": true, "size": "848M", "ro": false, "type": "rom", "mountpoint": null, "kname": "sr1", "fstype": "iso9660", "label": "Ubuntu-Server 18.04.3 LTS amd64", "uuid": "2019-08-05-20-00-00-00", "partlabel": null, "partuuid": null, "ra": 128, "model": "VMware SATA CD01", "serial": "01000000000000000001", "state": "running", "owner": "root", "group": "cdrom", "mode": "brw-rw----", "alignment": 0, "min_io": 2048, "opt_io": 0, "phy_sec": 2048, "log_sec": 2048, "rota": true, "sched": "cfq", "rq_size": 128, "disc_aln": 0, "disc_gran": "0B", "disc_max": "0B", "disc_zero": false, "wsame": "0B", "wwn": null, "rand": true, "pkname": null, "hctl": "3:0:0:0", "tran": "sata", "rev": "1.00", "vendor": "NECVMWar"}] +[{"name":"fd0","maj_min":"2:0","rm":true,"size":"1.4M","ro":false,"type":"disk","mountpoint":null,"kname":"fd0","fstype":null,"label":null,"uuid":null,"partlabel":null,"partuuid":null,"ra":128,"model":null,"serial":null,"state":null,"owner":"root","group":"disk","mode":"brw-rw----","alignment":0,"min_io":512,"opt_io":0,"phy_sec":512,"log_sec":512,"rota":true,"sched":"cfq","rq_size":128,"disc_aln":0,"disc_gran":"0B","disc_max":"0B","disc_zero":false,"wsame":"0B","wwn":null,"rand":true,"pkname":null,"hctl":null,"tran":null,"rev":null,"vendor":null,"size_bytes":1468006,"disc_gran_bytes":0,"disc_max_bytes":0,"wsame_bytes":0},{"name":"loop0","maj_min":"7:0","rm":false,"size":"54.5M","ro":true,"type":"loop","mountpoint":"/snap/core18/1223","kname":"loop0","fstype":"squashfs","label":null,"uuid":null,"partlabel":null,"partuuid":null,"ra":128,"model":null,"serial":null,"state":null,"owner":"root","group":"disk","mode":"brw-rw----","alignment":0,"min_io":512,"opt_io":0,"phy_sec":512,"log_sec":512,"rota":true,"sched":"none","rq_size":128,"disc_aln":0,"disc_gran":"4K","disc_max":"4G","disc_zero":false,"wsame":"0B","wwn":null,"rand":false,"pkname":null,"hctl":null,"tran":null,"rev":null,"vendor":null,"size_bytes":57147392,"disc_gran_bytes":4096,"disc_max_bytes":4294967296,"wsame_bytes":0},{"name":"loop1","maj_min":"7:1","rm":false,"size":"89.1M","ro":true,"type":"loop","mountpoint":"/snap/core/7917","kname":"loop1","fstype":"squashfs","label":null,"uuid":null,"partlabel":null,"partuuid":null,"ra":128,"model":null,"serial":null,"state":null,"owner":"root","group":"disk","mode":"brw-rw----","alignment":0,"min_io":512,"opt_io":0,"phy_sec":512,"log_sec":512,"rota":true,"sched":"none","rq_size":128,"disc_aln":0,"disc_gran":"4K","disc_max":"4G","disc_zero":false,"wsame":"0B","wwn":null,"rand":false,"pkname":null,"hctl":null,"tran":null,"rev":null,"vendor":null,"size_bytes":93428121,"disc_gran_bytes":4096,"disc_max_bytes":4294967296,"wsame_bytes":0},{"name":"loop2","maj_min":"7:2","rm":false,"size":"11M","ro":true,"type":"loop","mountpoint":"/snap/slcli/383","kname":"loop2","fstype":"squashfs","label":null,"uuid":null,"partlabel":null,"partuuid":null,"ra":128,"model":null,"serial":null,"state":null,"owner":"root","group":"disk","mode":"brw-rw----","alignment":0,"min_io":512,"opt_io":0,"phy_sec":512,"log_sec":512,"rota":true,"sched":"none","rq_size":128,"disc_aln":0,"disc_gran":"4K","disc_max":"4G","disc_zero":false,"wsame":"0B","wwn":null,"rand":false,"pkname":null,"hctl":null,"tran":null,"rev":null,"vendor":null,"size_bytes":11534336,"disc_gran_bytes":4096,"disc_max_bytes":4294967296,"wsame_bytes":0},{"name":"loop3","maj_min":"7:3","rm":false,"size":"8.6M","ro":true,"type":"loop","mountpoint":"/snap/doctl/215","kname":"loop3","fstype":"squashfs","label":null,"uuid":null,"partlabel":null,"partuuid":null,"ra":128,"model":null,"serial":null,"state":null,"owner":"root","group":"disk","mode":"brw-rw----","alignment":0,"min_io":512,"opt_io":0,"phy_sec":512,"log_sec":512,"rota":true,"sched":"none","rq_size":128,"disc_aln":0,"disc_gran":"4K","disc_max":"4G","disc_zero":false,"wsame":"0B","wwn":null,"rand":false,"pkname":null,"hctl":null,"tran":null,"rev":null,"vendor":null,"size_bytes":9017753,"disc_gran_bytes":4096,"disc_max_bytes":4294967296,"wsame_bytes":0},{"name":"loop4","maj_min":"7:4","rm":false,"size":"89.1M","ro":true,"type":"loop","mountpoint":"/snap/core/8039","kname":"loop4","fstype":"squashfs","label":null,"uuid":null,"partlabel":null,"partuuid":null,"ra":128,"model":null,"serial":null,"state":null,"owner":"root","group":"disk","mode":"brw-rw----","alignment":0,"min_io":512,"opt_io":0,"phy_sec":512,"log_sec":512,"rota":true,"sched":"none","rq_size":128,"disc_aln":0,"disc_gran":"4K","disc_max":"4G","disc_zero":false,"wsame":"0B","wwn":null,"rand":false,"pkname":null,"hctl":null,"tran":null,"rev":null,"vendor":null,"size_bytes":93428121,"disc_gran_bytes":4096,"disc_max_bytes":4294967296,"wsame_bytes":0},{"name":"loop5","maj_min":"7:5","rm":false,"size":"67M","ro":true,"type":"loop","mountpoint":"/snap/google-cloud-sdk/106","kname":"loop5","fstype":"squashfs","label":null,"uuid":null,"partlabel":null,"partuuid":null,"ra":128,"model":null,"serial":null,"state":null,"owner":"root","group":"disk","mode":"brw-rw----","alignment":0,"min_io":512,"opt_io":0,"phy_sec":512,"log_sec":512,"rota":true,"sched":"none","rq_size":128,"disc_aln":0,"disc_gran":"4K","disc_max":"4G","disc_zero":false,"wsame":"0B","wwn":null,"rand":false,"pkname":null,"hctl":null,"tran":null,"rev":null,"vendor":null,"size_bytes":70254592,"disc_gran_bytes":4096,"disc_max_bytes":4294967296,"wsame_bytes":0},{"name":"loop6","maj_min":"7:6","rm":false,"size":"66.8M","ro":true,"type":"loop","mountpoint":"/snap/google-cloud-sdk/105","kname":"loop6","fstype":"squashfs","label":null,"uuid":null,"partlabel":null,"partuuid":null,"ra":128,"model":null,"serial":null,"state":null,"owner":"root","group":"disk","mode":"brw-rw----","alignment":0,"min_io":512,"opt_io":0,"phy_sec":512,"log_sec":512,"rota":true,"sched":"none","rq_size":128,"disc_aln":0,"disc_gran":"4K","disc_max":"4G","disc_zero":false,"wsame":"0B","wwn":null,"rand":false,"pkname":null,"hctl":null,"tran":null,"rev":null,"vendor":null,"size_bytes":70044876,"disc_gran_bytes":4096,"disc_max_bytes":4294967296,"wsame_bytes":0},{"name":"loop7","maj_min":"7:7","rm":false,"size":"3.2M","ro":true,"type":"loop","mountpoint":"/snap/stress-ng/1046","kname":"loop7","fstype":"squashfs","label":null,"uuid":null,"partlabel":null,"partuuid":null,"ra":128,"model":null,"serial":null,"state":null,"owner":"root","group":"disk","mode":"brw-rw----","alignment":0,"min_io":512,"opt_io":0,"phy_sec":512,"log_sec":512,"rota":true,"sched":"none","rq_size":128,"disc_aln":0,"disc_gran":"4K","disc_max":"4G","disc_zero":false,"wsame":"0B","wwn":null,"rand":false,"pkname":null,"hctl":null,"tran":null,"rev":null,"vendor":null,"size_bytes":3355443,"disc_gran_bytes":4096,"disc_max_bytes":4294967296,"wsame_bytes":0},{"name":"loop8","maj_min":"7:8","rm":false,"size":"8.7M","ro":true,"type":"loop","mountpoint":"/snap/doctl/222","kname":"loop8","fstype":"squashfs","label":null,"uuid":null,"partlabel":null,"partuuid":null,"ra":128,"model":null,"serial":null,"state":null,"owner":"root","group":"disk","mode":"brw-rw----","alignment":0,"min_io":512,"opt_io":0,"phy_sec":512,"log_sec":512,"rota":true,"sched":"none","rq_size":128,"disc_aln":0,"disc_gran":"4K","disc_max":"4G","disc_zero":false,"wsame":"0B","wwn":null,"rand":false,"pkname":null,"hctl":null,"tran":null,"rev":null,"vendor":null,"size_bytes":9122611,"disc_gran_bytes":4096,"disc_max_bytes":4294967296,"wsame_bytes":0},{"name":"loop9","maj_min":"7:9","rm":false,"size":"54.5M","ro":true,"type":"loop","mountpoint":"/snap/core18/1265","kname":"loop9","fstype":"squashfs","label":null,"uuid":null,"partlabel":null,"partuuid":null,"ra":128,"model":null,"serial":null,"state":null,"owner":"root","group":"disk","mode":"brw-rw----","alignment":0,"min_io":512,"opt_io":0,"phy_sec":512,"log_sec":512,"rota":true,"sched":"none","rq_size":128,"disc_aln":0,"disc_gran":"4K","disc_max":"4G","disc_zero":false,"wsame":"0B","wwn":null,"rand":false,"pkname":null,"hctl":null,"tran":null,"rev":null,"vendor":null,"size_bytes":57147392,"disc_gran_bytes":4096,"disc_max_bytes":4294967296,"wsame_bytes":0},{"name":"loop10","maj_min":"7:10","rm":false,"size":"3.2M","ro":true,"type":"loop","mountpoint":"/snap/stress-ng/1076","kname":"loop10","fstype":"squashfs","label":null,"uuid":null,"partlabel":null,"partuuid":null,"ra":128,"model":null,"serial":null,"state":null,"owner":"root","group":"disk","mode":"brw-rw----","alignment":0,"min_io":512,"opt_io":0,"phy_sec":512,"log_sec":512,"rota":true,"sched":"none","rq_size":128,"disc_aln":0,"disc_gran":"4K","disc_max":"4G","disc_zero":false,"wsame":"0B","wwn":null,"rand":false,"pkname":null,"hctl":null,"tran":null,"rev":null,"vendor":null,"size_bytes":3355443,"disc_gran_bytes":4096,"disc_max_bytes":4294967296,"wsame_bytes":0},{"name":"sda","maj_min":"8:0","rm":false,"size":"20G","ro":false,"type":"disk","mountpoint":null,"kname":"sda","fstype":null,"label":null,"uuid":null,"partlabel":null,"partuuid":null,"ra":128,"model":"VMware Virtual S","serial":null,"state":"running","owner":"root","group":"disk","mode":"brw-rw----","alignment":0,"min_io":512,"opt_io":0,"phy_sec":512,"log_sec":512,"rota":true,"sched":"cfq","rq_size":128,"disc_aln":0,"disc_gran":"0B","disc_max":"0B","disc_zero":false,"wsame":"0B","wwn":null,"rand":true,"pkname":null,"hctl":"32:0:0:0","tran":"spi","rev":"1.0","vendor":"VMware,","size_bytes":21474836480,"disc_gran_bytes":0,"disc_max_bytes":0,"wsame_bytes":0},{"name":"sda1","maj_min":"8:1","rm":false,"size":"1M","ro":false,"type":"part","mountpoint":null,"kname":"sda1","fstype":null,"label":null,"uuid":null,"partlabel":null,"partuuid":"e0614271-c211-4324-a5bc-8e6bcb66da43","ra":128,"model":null,"serial":null,"state":null,"owner":"root","group":"disk","mode":"brw-rw----","alignment":0,"min_io":512,"opt_io":0,"phy_sec":512,"log_sec":512,"rota":true,"sched":"cfq","rq_size":128,"disc_aln":0,"disc_gran":"0B","disc_max":"0B","disc_zero":false,"wsame":"0B","wwn":null,"rand":true,"pkname":"sda","hctl":null,"tran":null,"rev":null,"vendor":null,"size_bytes":1048576,"disc_gran_bytes":0,"disc_max_bytes":0,"wsame_bytes":0},{"name":"sda2","maj_min":"8:2","rm":false,"size":"20G","ro":false,"type":"part","mountpoint":"/","kname":"sda2","fstype":"ext4","label":null,"uuid":"011527a0-c72a-4c00-a50e-ee90da26b6e2","partlabel":null,"partuuid":"744589e8-5711-4750-9984-c34d66f93879","ra":128,"model":null,"serial":null,"state":null,"owner":"root","group":"disk","mode":"brw-rw----","alignment":0,"min_io":512,"opt_io":0,"phy_sec":512,"log_sec":512,"rota":true,"sched":"cfq","rq_size":128,"disc_aln":0,"disc_gran":"0B","disc_max":"0B","disc_zero":false,"wsame":"0B","wwn":null,"rand":true,"pkname":"sda","hctl":null,"tran":null,"rev":null,"vendor":null,"size_bytes":21474836480,"disc_gran_bytes":0,"disc_max_bytes":0,"wsame_bytes":0},{"name":"sr0","maj_min":"11:0","rm":true,"size":"64.8M","ro":false,"type":"rom","mountpoint":null,"kname":"sr0","fstype":"iso9660","label":"CDROM","uuid":"2019-08-12-10-17-03-63","partlabel":null,"partuuid":null,"ra":128,"model":"VMware SATA CD00","serial":"00000000000000000001","state":"running","owner":"root","group":"cdrom","mode":"brw-rw----","alignment":0,"min_io":2048,"opt_io":0,"phy_sec":2048,"log_sec":2048,"rota":true,"sched":"cfq","rq_size":128,"disc_aln":0,"disc_gran":"0B","disc_max":"0B","disc_zero":false,"wsame":"0B","wwn":null,"rand":true,"pkname":null,"hctl":"2:0:0:0","tran":"sata","rev":"1.00","vendor":"NECVMWar","size_bytes":67947724,"disc_gran_bytes":0,"disc_max_bytes":0,"wsame_bytes":0},{"name":"sr1","maj_min":"11:1","rm":true,"size":"848M","ro":false,"type":"rom","mountpoint":null,"kname":"sr1","fstype":"iso9660","label":"Ubuntu-Server 18.04.3 LTS amd64","uuid":"2019-08-05-20-00-00-00","partlabel":null,"partuuid":null,"ra":128,"model":"VMware SATA CD01","serial":"01000000000000000001","state":"running","owner":"root","group":"cdrom","mode":"brw-rw----","alignment":0,"min_io":2048,"opt_io":0,"phy_sec":2048,"log_sec":2048,"rota":true,"sched":"cfq","rq_size":128,"disc_aln":0,"disc_gran":"0B","disc_max":"0B","disc_zero":false,"wsame":"0B","wwn":null,"rand":true,"pkname":null,"hctl":"3:0:0:0","tran":"sata","rev":"1.00","vendor":"NECVMWar","size_bytes":889192448,"disc_gran_bytes":0,"disc_max_bytes":0,"wsame_bytes":0}] diff --git a/tests/fixtures/ubuntu-18.04/lsblk.json b/tests/fixtures/ubuntu-18.04/lsblk.json index 5fc629a0..d710d02f 100644 --- a/tests/fixtures/ubuntu-18.04/lsblk.json +++ b/tests/fixtures/ubuntu-18.04/lsblk.json @@ -1 +1 @@ -[{"name": "fd0", "maj_min": "2:0", "rm": true, "size": "1.4M", "ro": false, "type": "disk", "mountpoint": null}, {"name": "loop0", "maj_min": "7:0", "rm": false, "size": "54.5M", "ro": true, "type": "loop", "mountpoint": "/snap/core18/1223"}, {"name": "loop1", "maj_min": "7:1", "rm": false, "size": "11M", "ro": true, "type": "loop", "mountpoint": "/snap/slcli/383"}, {"name": "loop2", "maj_min": "7:2", "rm": false, "size": "88.7M", "ro": true, "type": "loop", "mountpoint": "/snap/core/7396"}, {"name": "loop3", "maj_min": "7:3", "rm": false, "size": "66.5M", "ro": true, "type": "loop", "mountpoint": "/snap/google-cloud-sdk/103"}, {"name": "loop4", "maj_min": "7:4", "rm": false, "size": "66.5M", "ro": true, "type": "loop", "mountpoint": "/snap/google-cloud-sdk/104"}, {"name": "loop5", "maj_min": "7:5", "rm": false, "size": "54.4M", "ro": true, "type": "loop", "mountpoint": "/snap/core18/1074"}, {"name": "loop7", "maj_min": "7:7", "rm": false, "size": "8.6M", "ro": true, "type": "loop", "mountpoint": "/snap/doctl/187"}, {"name": "loop8", "maj_min": "7:8", "rm": false, "size": "3.1M", "ro": true, "type": "loop", "mountpoint": "/snap/stress-ng/847"}, {"name": "loop9", "maj_min": "7:9", "rm": false, "size": "8.6M", "ro": true, "type": "loop", "mountpoint": "/snap/doctl/215"}, {"name": "loop10", "maj_min": "7:10", "rm": false, "size": "89.1M", "ro": true, "type": "loop", "mountpoint": "/snap/core/7917"}, {"name": "loop11", "maj_min": "7:11", "rm": false, "size": "3.2M", "ro": true, "type": "loop", "mountpoint": "/snap/stress-ng/924"}, {"name": "sda", "maj_min": "8:0", "rm": false, "size": "20G", "ro": false, "type": "disk", "mountpoint": null}, {"name": "sda1", "maj_min": "8:1", "rm": false, "size": "1M", "ro": false, "type": "part", "mountpoint": null}, {"name": "sda2", "maj_min": "8:2", "rm": false, "size": "20G", "ro": false, "type": "part", "mountpoint": "/"}, {"name": "sr0", "maj_min": "11:0", "rm": true, "size": "64.8M", "ro": false, "type": "rom", "mountpoint": null}, {"name": "sr1", "maj_min": "11:1", "rm": true, "size": "848M", "ro": false, "type": "rom", "mountpoint": null}] +[{"name":"fd0","maj_min":"2:0","rm":true,"size":"1.4M","ro":false,"type":"disk","mountpoint":null,"size_bytes":1468006},{"name":"loop0","maj_min":"7:0","rm":false,"size":"54.5M","ro":true,"type":"loop","mountpoint":"/snap/core18/1223","size_bytes":57147392},{"name":"loop1","maj_min":"7:1","rm":false,"size":"11M","ro":true,"type":"loop","mountpoint":"/snap/slcli/383","size_bytes":11534336},{"name":"loop2","maj_min":"7:2","rm":false,"size":"88.7M","ro":true,"type":"loop","mountpoint":"/snap/core/7396","size_bytes":93008691},{"name":"loop3","maj_min":"7:3","rm":false,"size":"66.5M","ro":true,"type":"loop","mountpoint":"/snap/google-cloud-sdk/103","size_bytes":69730304},{"name":"loop4","maj_min":"7:4","rm":false,"size":"66.5M","ro":true,"type":"loop","mountpoint":"/snap/google-cloud-sdk/104","size_bytes":69730304},{"name":"loop5","maj_min":"7:5","rm":false,"size":"54.4M","ro":true,"type":"loop","mountpoint":"/snap/core18/1074","size_bytes":57042534},{"name":"loop7","maj_min":"7:7","rm":false,"size":"8.6M","ro":true,"type":"loop","mountpoint":"/snap/doctl/187","size_bytes":9017753},{"name":"loop8","maj_min":"7:8","rm":false,"size":"3.1M","ro":true,"type":"loop","mountpoint":"/snap/stress-ng/847","size_bytes":3250585},{"name":"loop9","maj_min":"7:9","rm":false,"size":"8.6M","ro":true,"type":"loop","mountpoint":"/snap/doctl/215","size_bytes":9017753},{"name":"loop10","maj_min":"7:10","rm":false,"size":"89.1M","ro":true,"type":"loop","mountpoint":"/snap/core/7917","size_bytes":93428121},{"name":"loop11","maj_min":"7:11","rm":false,"size":"3.2M","ro":true,"type":"loop","mountpoint":"/snap/stress-ng/924","size_bytes":3355443},{"name":"sda","maj_min":"8:0","rm":false,"size":"20G","ro":false,"type":"disk","mountpoint":null,"size_bytes":21474836480},{"name":"sda1","maj_min":"8:1","rm":false,"size":"1M","ro":false,"type":"part","mountpoint":null,"size_bytes":1048576},{"name":"sda2","maj_min":"8:2","rm":false,"size":"20G","ro":false,"type":"part","mountpoint":"/","size_bytes":21474836480},{"name":"sr0","maj_min":"11:0","rm":true,"size":"64.8M","ro":false,"type":"rom","mountpoint":null,"size_bytes":67947724},{"name":"sr1","maj_min":"11:1","rm":true,"size":"848M","ro":false,"type":"rom","mountpoint":null,"size_bytes":889192448}] diff --git a/tests/templates/.DS_Store b/tests/templates/.DS_Store deleted file mode 100644 index 5008ddfc..00000000 Binary files a/tests/templates/.DS_Store and /dev/null differ diff --git a/tests/test_amixer.py b/tests/test_amixer.py index bfa21616..d333d54f 100644 --- a/tests/test_amixer.py +++ b/tests/test_amixer.py @@ -22,27 +22,49 @@ class AmixerTests(unittest.TestCase): self.test_files_json = [f'{file}.json' for file in self.TEST_FILES_NAME] self.test_files_processed_json = [f'{file}-processed.json' for file in self.TEST_FILES_NAME] + def test_amixer_sget_nodata(self): + """ + Test 'amixer' with no data + """ + self.assertEqual(jc.parsers.amixer.parse('', quiet=True), {}) + def test_amixer_sget(self): for file_out, file_json, file_processed_json in zip(self.test_files_out, self.test_files_json, self.test_files_processed_json): with open(file_out, 'r') as f: - amixer_sget_raw_output: str = f.read() + amixer_sget_raw_output = f.read() with open(file_json, 'r') as f: - expected_amixer_sget_json_output: str = f.read() - expected_amixer_sget_json_map: dict = json.loads(expected_amixer_sget_json_output) + expected_amixer_sget_json_output = f.read() + expected_amixer_sget_json_map = json.loads(expected_amixer_sget_json_output) with open(file_processed_json, 'r') as f: - expected_amixer_sget_processed_json_output: str = f.read() - expected_amixer_sget_processed_json_map: dict = json.loads(expected_amixer_sget_processed_json_output) + expected_amixer_sget_processed_json_output = f.read() + expected_amixer_sget_processed_json_map = json.loads(expected_amixer_sget_processed_json_output) # Tests for raw=True - amixer_sget_json_map: dict = jc.parse(self.AMIXER_CMD, amixer_sget_raw_output, raw=True, + amixer_sget_json_map = jc.parse(self.AMIXER_CMD, amixer_sget_raw_output, raw=True, quiet=True) self.assertEqual(amixer_sget_json_map, expected_amixer_sget_json_map) # Tests for raw=False process - amixer_sget_json_processed_map: dict = jc.parse(self.AMIXER_CMD, amixer_sget_raw_output, raw=False, + amixer_sget_json_processed_map = jc.parse(self.AMIXER_CMD, amixer_sget_raw_output, raw=False, quiet=True) self.assertEqual(amixer_sget_json_processed_map, expected_amixer_sget_processed_json_map) + def test_amixer_missing_db(self): + data = '''Simple mixer control 'Master',0 + Capabilities: pvolume pswitch pswitch-joined + Playback channels: Front Left - Front Right + Limits: Playback 0 - 65536 + Mono: + Front Left: Playback 55039 [84%] [on] + Front Right: Playback 54383 [83%] [on] +Simple mixer control 'Capture',0 + Capabilities: cvolume cswitch cswitch-joined + Capture channels: Front Left - Front Right + Limits: Capture 0 - 65536 + Front Left: Capture 24672 [38%] [on] + Front Right: Capture 24672 [38%] [on]''' + expected = {"control_name":"Master","capabilities":["cvolume","cswitch","cswitch-joined"],"playback_channels":["Front Left","Front Right"],"limits":{"playback_min":0,"playback_max":65536},"front_left":{"playback_value":24672,"percentage":38,"db":0.0,"status":True},"front_right":{"playback_value":24672,"percentage":38,"db":0.0,"status":True}} + self.assertEqual(expected, jc.parsers.amixer.parse(data, quiet=True)) if __name__ == '__main__': unittest.main() diff --git a/tests/test_bluetoothctl.py b/tests/test_bluetoothctl.py index 1df04213..85076103 100644 --- a/tests/test_bluetoothctl.py +++ b/tests/test_bluetoothctl.py @@ -104,7 +104,48 @@ class BluetoothctlTests(unittest.TestCase): if actual: for k, v in expected.items(): self.assertEqual(v, actual[0][k], f"Controller regex failed on {k}") - + + def test_bluetoothctl_controller_2(self): + """ + Test 'bluetoothctl' with controller 2 + """ + + with open("tests/fixtures/generic/bluetoothctl_controller_2.out", "r") as f: + output = f.read() + + actual = parse(output, quiet=True) + + self.assertIsNotNone(actual) + self.assertIsNotNone(actual[0]) + + expected = { + "address": "CC:52:AF:17:6A:E4", + "is_public": True, + "name": "starbase", + "alias": "starbase", + "class": "0x006c010c (7078156)", + "powered": "yes", + "power_state": "on", + "discoverable": "no", + "discoverable_timeout": "0x000000b4 (180)", + "pairable": "no", + "uuids": [ + "Handsfree (0000111e-0000-1000-8000-00805f9b34fb)", + "Audio Source (0000110a-0000-1000-8000-00805f9b34fb)", + "Audio Sink (0000110b-0000-1000-8000-00805f9b34fb)", + "PnP Information (00001200-0000-1000-8000-00805f9b34fb)", + "A/V Remote Control Target (0000110c-0000-1000-8000-00805f9b34fb)", + "A/V Remote Control (0000110e-0000-1000-8000-00805f9b34fb)", + "Handsfree Audio Gateway (0000111f-0000-1000-8000-00805f9b34fb)" + ], + "modalias": "usb:v1D6Bp0246d054F", + "discovering": "no" + } + + if actual: + for k, v in expected.items(): + self.assertEqual(v, actual[0][k], f"Controller regex failed on {k}") + def test_bluetoothctl_controller_with_manufacturer(self): """ Test 'bluetoothctl' with controller having manufacturer attr diff --git a/tests/test_iptables.py b/tests/test_iptables.py index 124a54e0..e94ea806 100644 --- a/tests/test_iptables.py +++ b/tests/test_iptables.py @@ -200,7 +200,7 @@ class MyTests(unittest.TestCase): 128627559125 172804718595966 INPUT_ZONES all -- * * 0.0.0.0/0 0.0.0.0/0 26599 1082920 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate INVALID 1761 79571 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited''' - expected = [{"chain":"INPUT","rules":[{"pkts":11291792498,"bytes":217331852907122,"target":"ACCEPT","prot":"all","opt":None,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"ctstate RELATED,ESTABLISHED"},{"pkts":555958,"bytes":33533576,"target":"ACCEPT","prot":"all","opt":None,"in":"lo","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":128628404869,"bytes":172804745659762,"target":"INPUT_direct","prot":"all","opt":None,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":128627559128,"bytes":172804718596050,"target":"INPUT_ZONES_SOURCE","prot":"all","opt":None,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":128627559125,"bytes":172804718595966,"target":"INPUT_ZONES","prot":"all","opt":None,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0"},{"pkts":26599,"bytes":1082920,"target":"DROP","prot":"all","opt":None,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"ctstate INVALID"},{"pkts":1761,"bytes":79571,"target":"REJECT","prot":"all","opt":None,"in":"*","out":"*","source":"0.0.0.0/0","destination":"0.0.0.0/0","options":"reject-with icmp-host-prohibited"}]}] + expected = [{'chain': 'INPUT', 'default_policy': 'ACCEPT', 'default_packets': 0, 'default_bytes': 0, 'rules': [{'pkts': 11291792498, 'bytes': 217331852907122, 'target': 'ACCEPT', 'prot': 'all', 'opt': None, 'in': '*', 'out': '*', 'source': '0.0.0.0/0', 'destination': '0.0.0.0/0', 'options': 'ctstate RELATED,ESTABLISHED'}, {'pkts': 555958, 'bytes': 33533576, 'target': 'ACCEPT', 'prot': 'all', 'opt': None, 'in': 'lo', 'out': '*', 'source': '0.0.0.0/0', 'destination': '0.0.0.0/0'}, {'pkts': 128628404869, 'bytes': 172804745659762, 'target': 'INPUT_direct', 'prot': 'all', 'opt': None, 'in': '*', 'out': '*', 'source': '0.0.0.0/0', 'destination': '0.0.0.0/0'}, {'pkts': 128627559128, 'bytes': 172804718596050, 'target': 'INPUT_ZONES_SOURCE', 'prot': 'all', 'opt': None, 'in': '*', 'out': '*', 'source': '0.0.0.0/0', 'destination': '0.0.0.0/0'}, {'pkts': 128627559125, 'bytes': 172804718595966, 'target': 'INPUT_ZONES', 'prot': 'all', 'opt': None, 'in': '*', 'out': '*', 'source': '0.0.0.0/0', 'destination': '0.0.0.0/0'}, {'pkts': 26599, 'bytes': 1082920, 'target': 'DROP', 'prot': 'all', 'opt': None, 'in': '*', 'out': '*', 'source': '0.0.0.0/0', 'destination': '0.0.0.0/0', 'options': 'ctstate INVALID'}, {'pkts': 1761, 'bytes': 79571, 'target': 'REJECT', 'prot': 'all', 'opt': None, 'in': '*', 'out': '*', 'source': '0.0.0.0/0', 'destination': '0.0.0.0/0', 'options': 'reject-with icmp-host-prohibited'}]}] self.assertEqual(jc.parsers.iptables.parse(data, quiet=True), expected) diff --git a/tests/test_lsblk.py b/tests/test_lsblk.py index ca549971..a9eab374 100644 --- a/tests/test_lsblk.py +++ b/tests/test_lsblk.py @@ -65,6 +65,24 @@ class MyTests(unittest.TestCase): """ self.assertEqual(jc.parsers.lsblk.parse(self.ubuntu_18_4_lsblk_allcols, quiet=True), self.ubuntu_18_4_lsblk_allcols_json) + def test_lsblk_multiple_mountpoints(self): + """ + Test 'lsblk' with multiple mountpoints + """ + data = '''NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS +sda 8:0 0 5368709120000 0 disk +|-sda1 8:1 0 1048576 0 part +|-sda2 8:2 0 1073741824 0 part /boot +|-sda3 8:3 0 1073741824 0 part /boot/efi +`-sda4 8:4 0 51536461824 0 part + |-almalinux-root 253:0 0 36075208704 0 lvm / + |-almalinux-docker 253:1 0 1073741824 0 lvm /opt/docker + |-almalinux-home 253:2 0 5368709120 0 lvm /home + `-almalinux-opt 253:3 0 9017753600 0 lvm /var/lib/kafka + /opt +sr0 11:0 1 1073741312 0 rom''' + expected = [{"name":"sda","maj_min":"8:0","rm":False,"size":"5368709120000","ro":False,"type":"disk","mountpoints":[],"size_bytes":5368709120000},{"name":"sda1","maj_min":"8:1","rm":False,"size":"1048576","ro":False,"type":"part","mountpoints":[],"size_bytes":1048576},{"name":"sda2","maj_min":"8:2","rm":False,"size":"1073741824","ro":False,"type":"part","mountpoints":["/boot"],"size_bytes":1073741824},{"name":"sda3","maj_min":"8:3","rm":False,"size":"1073741824","ro":False,"type":"part","mountpoints":["/boot/efi"],"size_bytes":1073741824},{"name":"sda4","maj_min":"8:4","rm":False,"size":"51536461824","ro":False,"type":"part","mountpoints":[],"size_bytes":51536461824},{"name":"almalinux-root","maj_min":"253:0","rm":False,"size":"36075208704","ro":False,"type":"lvm","mountpoints":["/"],"size_bytes":36075208704},{"name":"almalinux-docker","maj_min":"253:1","rm":False,"size":"1073741824","ro":False,"type":"lvm","mountpoints":["/opt/docker"],"size_bytes":1073741824},{"name":"almalinux-home","maj_min":"253:2","rm":False,"size":"5368709120","ro":False,"type":"lvm","mountpoints":["/home"],"size_bytes":5368709120},{"name":"almalinux-opt","maj_min":"253:3","rm":False,"size":"9017753600","ro":False,"type":"lvm","mountpoints":["/var/lib/kafka","/opt"],"size_bytes":9017753600},{"name":"sr0","maj_min":"11:0","rm":True,"size":"1073741312","ro":False,"type":"rom","mountpoints":[],"size_bytes":1073741312}] + self.assertEqual(jc.parsers.lsblk.parse(data, quiet=True), expected) if __name__ == '__main__': unittest.main() diff --git a/tests/test_mount.py b/tests/test_mount.py index 895730cb..2d6b88f9 100644 --- a/tests/test_mount.py +++ b/tests/test_mount.py @@ -30,6 +30,9 @@ class MyTests(unittest.TestCase): with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/mount-spaces-in-filename.out'), 'r', encoding='utf-8') as f: generic_mount_spaces_in_filename = f.read() + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/mount-parens-in-filesystem.out'), 'r', encoding='utf-8') as f: + generic_mount_parens_in_filesystem = f.read() + # output with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/mount.json'), 'r', encoding='utf-8') as f: @@ -53,6 +56,9 @@ class MyTests(unittest.TestCase): with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/mount-spaces-in-filename.json'), 'r', encoding='utf-8') as f: generic_mount_spaces_in_filename_json = json.loads(f.read()) + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/mount-parens-in-filesystem.json'), 'r', encoding='utf-8') as f: + generic_mount_parens_in_filesystem_json = json.loads(f.read()) + def test_mount_nodata(self): """ @@ -102,6 +108,12 @@ class MyTests(unittest.TestCase): """ self.assertEqual(jc.parsers.mount.parse(self.generic_mount_spaces_in_filename, quiet=True), self.generic_mount_spaces_in_filename_json) + def test_mount_parens_in_filesystem(self): + """ + Test 'mount' with parenthesis in the filesystem + """ + self.assertEqual(jc.parsers.mount.parse(self.generic_mount_parens_in_filesystem, quiet=True), self.generic_mount_parens_in_filesystem_json) + if __name__ == '__main__': unittest.main() diff --git a/tests/test_nmcli.py b/tests/test_nmcli.py index 7f0eb4ab..5bb90dfa 100644 --- a/tests/test_nmcli.py +++ b/tests/test_nmcli.py @@ -185,6 +185,117 @@ class MyTests(unittest.TestCase): """ self.assertEqual(jc.parsers.nmcli.parse(self.fedora32_nmcli_device_show, quiet=True), self.fedora32_nmcli_device_show_json) + def test_nmcli_team_config(self): + """ + Test nmcli with team.config JSON value + """ + data = '''connection.id: Team connection 1 +connection.uuid: 258e02c2-d9f9-44bb-8d27-887e11aa1828 +connection.stable-id: -- +connection.type: team +connection.interface-name: team0 +connection.autoconnect: yes +connection.autoconnect-priority: 0 +connection.autoconnect-retries: -1 (default) +connection.multi-connect: 0 (default) +connection.auth-retries: -1 +connection.timestamp: 0 +connection.read-only: no +connection.permissions: -- +connection.zone: -- +connection.master: -- +connection.slave-type: -- +connection.autoconnect-slaves: -1 (default) +connection.secondaries: -- +connection.gateway-ping-timeout: 0 +connection.metered: unknown +connection.lldp: default +connection.mdns: -1 (default) +connection.llmnr: -1 (default) +connection.dns-over-tls: -1 (default) +connection.wait-device-timeout: -1 +ipv4.method: auto +ipv4.dns: -- +ipv4.dns-search: -- +ipv4.dns-options: -- +ipv4.dns-priority: 0 +ipv4.addresses: -- +ipv4.gateway: -- +ipv4.routes: -- +ipv4.route-metric: -1 +ipv4.route-table: 0 (unspec) +ipv4.routing-rules: -- +ipv4.ignore-auto-routes: no +ipv4.ignore-auto-dns: no +ipv4.dhcp-client-id: -- +ipv4.dhcp-iaid: -- +ipv4.dhcp-timeout: 0 (default) +ipv4.dhcp-send-hostname: yes +ipv4.dhcp-hostname: -- +ipv4.dhcp-fqdn: -- +ipv4.dhcp-hostname-flags: 0x0 (none) +ipv4.never-default: no +ipv4.may-fail: yes +ipv4.required-timeout: -1 (default) +ipv4.dad-timeout: -1 (default) +ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-reject-servers: -- +ipv6.method: auto +ipv6.dns: -- +ipv6.dns-search: -- +ipv6.dns-options: -- +ipv6.dns-priority: 0 +ipv6.addresses: -- +ipv6.gateway: -- +ipv6.routes: -- +ipv6.route-metric: -1 +ipv6.route-table: 0 (unspec) +ipv6.routing-rules: -- +ipv6.ignore-auto-routes: no +ipv6.ignore-auto-dns: no +ipv6.never-default: no +ipv6.may-fail: yes +ipv6.required-timeout: -1 (default) +ipv6.ip6-privacy: -1 (unknown) +ipv6.addr-gen-mode: stable-privacy +ipv6.ra-timeout: 0 (default) +ipv6.dhcp-duid: -- +ipv6.dhcp-iaid: -- +ipv6.dhcp-timeout: 0 (default) +ipv6.dhcp-send-hostname: yes +ipv6.dhcp-hostname: -- +ipv6.dhcp-hostname-flags: 0x0 (none) +ipv6.token: -- +team.config: { + "runner": { + "name": "roundrobin" + }, + "link_watch": { + "name": "ethtool" + } +} +team.notify-peers-count: -1 (unset) +team.notify-peers-interval: -1 (unset) +team.mcast-rejoin-count: -1 (unset) +team.mcast-rejoin-interval: -1 (unset) +team.runner: roundrobin +team.runner-hwaddr-policy: -- +team.runner-tx-hash: -- +team.runner-tx-balancer: -- +team.runner-tx-balancer-interval: -1 (unset) +team.runner-active: yes +team.runner-fast-rate: no +team.runner-sys-prio: -1 (unset) +team.runner-min-ports: -1 (unset) +team.runner-agg-select-policy: -- +team.link-watchers: name=ethtool +proxy.method: none +proxy.browser-only: no +proxy.pac-url: -- +proxy.pac-script: --''' + expected = [{'connection_id': 'Team connection 1', 'connection_uuid': '258e02c2-d9f9-44bb-8d27-887e11aa1828', 'connection_stable_id': None, 'connection_type': 'team', 'connection_interface_name': 'team0', 'connection_autoconnect': 'yes', 'connection_autoconnect_priority': 0, 'connection_autoconnect_retries': -1, 'connection_autoconnect_retries_text': 'default', 'connection_multi_connect': 0, 'connection_multi_connect_text': 'default', 'connection_auth_retries': -1, 'connection_timestamp': 0, 'connection_read_only': 'no', 'connection_permissions': None, 'connection_zone': None, 'connection_master': None, 'connection_slave_type': None, 'connection_autoconnect_slaves': -1, 'connection_autoconnect_slaves_text': 'default', 'connection_secondaries': None, 'connection_gateway_ping_timeout': 0, 'connection_metered': 'unknown', 'connection_lldp': 'default', 'connection_mdns': -1, 'connection_mdns_text': 'default', 'connection_llmnr': -1, 'connection_llmnr_text': 'default', 'connection_dns_over_tls': -1, 'connection_dns_over_tls_text': 'default', 'connection_wait_device_timeout': -1, 'ipv4_method': 'auto', 'ipv4_dns': None, 'ipv4_dns_search': None, 'ipv4_dns_options': None, 'ipv4_dns_priority': 0, 'ipv4_addresses': None, 'ipv4_gateway': None, 'ipv4_routes': None, 'ipv4_route_metric': -1, 'ipv4_route_table': 0, 'ipv4_route_table_text': 'unspec', 'ipv4_routing_rules': None, 'ipv4_ignore_auto_routes': 'no', 'ipv4_ignore_auto_dns': 'no', 'ipv4_dhcp_client_id': None, 'ipv4_dhcp_iaid': None, 'ipv4_dhcp_timeout': 0, 'ipv4_dhcp_timeout_text': 'default', 'ipv4_dhcp_send_hostname': 'yes', 'ipv4_dhcp_hostname': None, 'ipv4_dhcp_fqdn': None, 'ipv4_dhcp_hostname_flags': '0x0', 'ipv4_dhcp_hostname_flags_text': 'none', 'ipv4_never_default': 'no', 'ipv4_may_fail': 'yes', 'ipv4_required_timeout': -1, 'ipv4_required_timeout_text': 'default', 'ipv4_dad_timeout': -1, 'ipv4_dad_timeout_text': 'default', 'ipv4_dhcp_vendor_class_identifier': None, 'ipv4_dhcp_reject_servers': None, 'ipv6_method': 'auto', 'ipv6_dns': None, 'ipv6_dns_search': None, 'ipv6_dns_options': None, 'ipv6_dns_priority': 0, 'ipv6_addresses': None, 'ipv6_gateway': None, 'ipv6_routes': None, 'ipv6_route_metric': -1, 'ipv6_route_table': 0, 'ipv6_route_table_text': 'unspec', 'ipv6_routing_rules': None, 'ipv6_ignore_auto_routes': 'no', 'ipv6_ignore_auto_dns': 'no', 'ipv6_never_default': 'no', 'ipv6_may_fail': 'yes', 'ipv6_required_timeout': -1, 'ipv6_required_timeout_text': 'default', 'ipv6_ip6_privacy': -1, 'ipv6_ip6_privacy_text': 'unknown', 'ipv6_addr_gen_mode': 'stable-privacy', 'ipv6_ra_timeout': 0, 'ipv6_ra_timeout_text': 'default', 'ipv6_dhcp_duid': None, 'ipv6_dhcp_iaid': None, 'ipv6_dhcp_timeout': 0, 'ipv6_dhcp_timeout_text': 'default', 'ipv6_dhcp_send_hostname': 'yes', 'ipv6_dhcp_hostname': None, 'ipv6_dhcp_hostname_flags': '0x0', 'ipv6_dhcp_hostname_flags_text': 'none', 'ipv6_token': None, 'team_config': {'runner': {'name': 'roundrobin'}, 'link_watch': {'name': 'ethtool'}}, 'team_notify_peers_count': -1, 'team_notify_peers_count_text': 'unset', 'team_notify_peers_interval': -1, 'team_notify_peers_interval_text': 'unset', 'team_mcast_rejoin_count': -1, 'team_mcast_rejoin_count_text': 'unset', 'team_mcast_rejoin_interval': -1, 'team_mcast_rejoin_interval_text': 'unset', 'team_runner': 'roundrobin', 'team_runner_hwaddr_policy': None, 'team_runner_tx_hash': None, 'team_runner_tx_balancer': None, 'team_runner_tx_balancer_interval': -1, 'team_runner_tx_balancer_interval_text': 'unset', 'team_runner_active': 'yes', 'team_runner_fast_rate': 'no', 'team_runner_sys_prio': -1, 'team_runner_sys_prio_text': 'unset', 'team_runner_min_ports': -1, 'team_runner_min_ports_text': 'unset', 'team_runner_agg_select_policy': None, 'team_link_watchers': 'name=ethtool', 'proxy_method': 'none', 'proxy_browser_only': 'no', 'proxy_pac_url': None, 'proxy_pac_script': None}] + self.assertEqual(jc.parsers.nmcli.parse(data, quiet=True), expected) + if __name__ == '__main__': unittest.main() diff --git a/tests/test_time.py b/tests/test_time.py index eaa08b0b..795e2c75 100644 --- a/tests/test_time.py +++ b/tests/test_time.py @@ -113,6 +113,37 @@ class MyTests(unittest.TestCase): """ self.assertEqual(jc.parsers.time.parse(self.osx_10_14_6_time_lp, quiet=True), self.osx_10_14_6_time_lp_json) + def test_time_no_centiseconds(self): + """ + Test 'time' output with no centiseconds data + """ + data = ''' Command being timed: "echo" + User time (seconds): 5156.20 + System time (seconds): 0.05 + Percent of CPU this job got: 99% + Elapsed (wall clock) time (h:mm:ss or m:ss): 1:25:56 + Average shared text size (kbytes): 0 + Average unshared data size (kbytes): 0 + Average stack size (kbytes): 0 + Average total size (kbytes): 0 + Maximum resident set size (kbytes): 21760 + Average resident set size (kbytes): 0 + Major (requiring I/O) page faults: 0 + Minor (reclaiming a frame) page faults: 4975 + Voluntary context switches: 1 + Involuntary context switches: 8159 + Swaps: 0 + File system inputs: 0 + File system outputs: 6272 + Socket messages sent: 0 + Socket messages received: 0 + Signals delivered: 0 + Page size (bytes): 4096 + Exit status: 0''' + + expected = {"command_being_timed":"echo","user_time":5156.2,"system_time":0.05,"cpu_percent":99,"elapsed_time":"1:25:56","average_shared_text_size":0,"average_unshared_data_size":0,"average_stack_size":0,"average_total_size":0,"maximum_resident_set_size":21760,"average_resident_set_size":0,"major_pagefaults":0,"minor_pagefaults":4975,"voluntary_context_switches":1,"involuntary_context_switches":8159,"swaps":0,"block_input_operations":0,"block_output_operations":6272,"messages_sent":0,"messages_received":0,"signals_delivered":0,"page_size":4096,"exit_status":0,"elapsed_time_hours":1,"elapsed_time_minutes":25,"elapsed_time_seconds":56,"elapsed_time_centiseconds":0,"elapsed_time_total_seconds":5156.0} + self.assertEqual(jc.parsers.time.parse(data, quiet=True), expected) + if __name__ == '__main__': unittest.main() diff --git a/tests/test_x509_cert.py b/tests/test_x509_cert.py index 36421d66..66a3b767 100644 --- a/tests/test_x509_cert.py +++ b/tests/test_x509_cert.py @@ -33,6 +33,9 @@ class MyTests(unittest.TestCase): with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/x509-negative-serial.pem'), 'rb') as f: x509_cert_negative_serial = f.read() + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/x509-cert-bad-email2.der'), 'rb') as f: + x509_cert_bad_email2 = f.read() + # output with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/x509-ca-cert.json'), 'r', encoding='utf-8') as f: x509_ca_cert_json = json.loads(f.read()) @@ -54,10 +57,13 @@ class MyTests(unittest.TestCase): with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/x509-cert-superfluous-bits.json'), 'r', encoding='utf-8') as f: x509_cert_superfluous_bits_json = json.loads(f.read()) - + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/x509-negative-serial.json'), 'r', encoding='utf-8') as f: x509_cert_negative_serial_json = json.loads(f.read()) + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/x509-cert-bad-email2.json'), 'r', encoding='utf-8') as f: + x509_cert_bad_email2_json = json.loads(f.read()) + def test_x509_cert_nodata(self): """ @@ -113,6 +119,12 @@ class MyTests(unittest.TestCase): """ self.assertEqual(jc.parsers.x509_cert.parse(self.x509_cert_negative_serial, quiet=True), self.x509_cert_negative_serial_json) + def test_x509_cert_bad_email2(self): + """ + Test 'cat x509-cert-bad-email2.der' (DER file with a non-compliant email address - IDNA2008 encoded) + """ + self.assertEqual(jc.parsers.x509_cert.parse(self.x509_cert_bad_email2, quiet=True), self.x509_cert_bad_email2_json) + if __name__ == '__main__': unittest.main()