From c6aa4d083550d25bcb621cad524047cfd6a08217 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Fri, 16 Apr 2021 16:19:20 -0700 Subject: [PATCH] update docs with new dig parser examples --- README.md | 84 +++++----- docs/parsers/dig.md | 313 +++++++++++--------------------------- jc/man/jc.1.gz | Bin 2051 -> 2061 bytes jc/parsers/dig.py | 88 ++++++++++- man/jc.1.gz | Bin 2051 -> 2061 bytes templates/readme_template | 84 +++++----- 6 files changed, 252 insertions(+), 317 deletions(-) diff --git a/README.md b/README.md index 1c5c3bef..f2646061 100644 --- a/README.md +++ b/README.md @@ -9,62 +9,56 @@ JSON CLI output utility `jc` JSONifies the output of many CLI tools and file-types for easier parsing in scripts. See the [**Parsers**](#parsers) section for supported commands and file-types. - -This allows further command-line processing of output with tools like `jq` by piping commands: ```bash -ls -l /usr/bin | jc --ls | jq '.[] | select(.size > 50000000)' +dig example.com | jc --dig ``` ```json -{ - "filename": "docker", - "flags": "-rwxr-xr-x", - "links": 1, - "owner": "root", - "group": "root", - "size": 68677120, - "date": "Aug 14 19:41" -} +[{"id":38052,"opcode":"QUERY","status":"NOERROR","flags":["qr","rd","ra"],"query_num":1,"answer_num":1, +"authority_num":0,"additional_num":1,"opt_pseudosection":{"edns":{"version":0,"flags":[],"udp":4096}},"question": +{"name":"example.com.","class":"IN","type":"A"},"answer":[{"name":"example.com.","class":"IN","type":"A","ttl": +39049,"data":"93.184.216.34"}],"query_time":49,"server":"2600:1700:bab0:d40::1#53(2600:1700:bab0:d40::1)","when": +"Fri Apr 16 16:09:00 PDT 2021","rcvd":56,"when_epoch":1618614540,"when_epoch_utc":null}] +``` +This allows further command-line processing of output with tools like `jq` by piping commands: +```bash +$ dig example.com | jc --dig | jq -r '.[].answer[].data' +93.184.216.34 ``` or using the alternative "magic" syntax: ```bash -jc ls -l /usr/bin | jq '.[] | select(.size > 50000000)' -``` -```json -{ - "filename": "docker", - "flags": "-rwxr-xr-x", - "links": 1, - "owner": "root", - "group": "root", - "size": 68677120, - "date": "Aug 14 19:41" -} +$ jc dig example.com | jq -r '.[].answer[].data' +93.184.216.34 ``` The `jc` parsers can also be used as python modules. In this case the output will be a python dictionary, or list of dictionaries, instead of JSON: ```python ->>> import jc.parsers.ls +>>> import jc.parsers.dig >>> ->>> data='''-rwxr-xr-x 1 root wheel 23648 May 3 22:26 cat -... -rwxr-xr-x 1 root wheel 30016 May 3 22:26 chmod -... -rwxr-xr-x 1 root wheel 29024 May 3 22:26 cp -... -rwxr-xr-x 1 root wheel 375824 May 3 22:26 csh -... -rwxr-xr-x 1 root wheel 28608 May 3 22:26 date -... -rwxr-xr-x 1 root wheel 32000 May 3 22:26 dd -... -rwxr-xr-x 1 root wheel 23392 May 3 22:26 df -... -rwxr-xr-x 1 root wheel 18128 May 3 22:26 echo''' +>>> data = '''; <<>> DiG 9.10.6 <<>> example.com +... ;; global options: +cmd +... ;; Got answer: +... ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64612 +... ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 +... +... ;; OPT PSEUDOSECTION: +... ; EDNS: version: 0, flags:; udp: 4096 +... ;; QUESTION SECTION: +... ;example.com. IN A +... +... ;; ANSWER SECTION: +... example.com. 29658 IN A 93.184.216.34 +... +... ;; Query time: 52 msec +... ;; SERVER: 2600:1700:bab0:d40::1#53(2600:1700:bab0:d40::1) +... ;; WHEN: Fri Apr 16 16:13:00 PDT 2021 +... ;; MSG SIZE rcvd: 56''' >>> ->>> jc.parsers.ls.parse(data) -[{'filename': 'cat', 'flags': '-rwxr-xr-x', 'links': 1, 'owner': 'root', 'group': 'wheel', 'size': 23648, -'date': 'May 3 22:26'}, {'filename': 'chmod', 'flags': '-rwxr-xr-x', 'links': 1, 'owner': 'root', -'group': 'wheel', 'size': 30016, 'date': 'May 3 22:26'}, {'filename': 'cp', 'flags': '-rwxr-xr-x', -'links': 1, 'owner': 'root', 'group': 'wheel', 'size': 29024, 'date': 'May 3 22:26'}, {'filename': 'csh', -'flags': '-rwxr-xr-x', 'links': 1, 'owner': 'root', 'group': 'wheel', 'size': 375824, 'date': 'May 3 -22:26'}, {'filename': 'date', 'flags': '-rwxr-xr-x', 'links': 1, 'owner': 'root', 'group': 'wheel', -'size': 28608, 'date': 'May 3 22:26'}, {'filename': 'dd', 'flags': '-rwxr-xr-x', 'links': 1, 'owner': -'root', 'group': 'wheel', 'size': 32000, 'date': 'May 3 22:26'}, {'filename': 'df', 'flags': -'-rwxr-xr-x', 'links': 1, 'owner': 'root', 'group': 'wheel', 'size': 23392, 'date': 'May 3 22:26'}, -{'filename': 'echo', 'flags': '-rwxr-xr-x', 'links': 1, 'owner': 'root', 'group': 'wheel', 'size': 18128, -'date': 'May 3 22:26'}] +>>> jc.parsers.dig.parse(data) +[{'id': 64612, 'opcode': 'QUERY', 'status': 'NOERROR', 'flags': ['qr', 'rd', 'ra'], 'query_num': 1, 'answer_num': +1, 'authority_num': 0, 'additional_num': 1, 'opt_pseudosection': {'edns': {'version': 0, 'flags': [], 'udp': +4096}}, 'question': {'name': 'example.com.', 'class': 'IN', 'type': 'A'}, 'answer': [{'name': 'example.com.', +'class': 'IN', 'type': 'A', 'ttl': 29658, 'data': '93.184.216.34'}], 'query_time': 52, 'server': +'2600:1700:bab0:d40::1#53(2600:1700:bab0:d40::1)', 'when': 'Fri Apr 16 16:13:00 PDT 2021', 'rcvd': 56, +'when_epoch': 1618614780, 'when_epoch_utc': None}] ``` Two representations of the data are possible. The default representation uses a strict schema per parser and converts known numbers to int/float JSON values. Certain known values of `None` are converted to JSON `null`, known boolean values are converted, and, in some cases, additional semantic context fields are added. diff --git a/docs/parsers/dig.md b/docs/parsers/dig.md index bf6ad803..92821c2d 100644 --- a/docs/parsers/dig.md +++ b/docs/parsers/dig.md @@ -24,64 +24,83 @@ Schema: [ { - "id": integer, - "opcode": string, - "status": string, + "id": integer, + "opcode": string, + "status": string, "flags": [ - string + string ], - "query_num": integer, - "answer_num": integer, - "authority_num": integer, - "additional_num": integer, + "query_num": integer, + "answer_num": integer, + "authority_num": integer, + "additional_num": integer, "axfr": [ { - "name": string, - "class": string, - "type": string, - "ttl": integer, - "data": string + "name": string, + "class": string, + "type": string, + "ttl": integer, + "data": string } ], + "opt_pseudosection": { + "edns": { + "version": integer, + "flags": [ + string + ], + "udp": integer + }, + "cookie": string + }, "question": { - "name": string, - "class": string, - "type": string + "name": string, + "class": string, + "type": string }, "answer": [ { - "name": string, - "class": string, - "type": string, - "ttl": integer, - "data": string + "name": string, + "class": string, + "type": string, + "ttl": integer, + "data": string + } + ], + "additional": [ + { + "name": string, + "class": string, + "type": string, + "ttl": integer, + "data": string } ], "authority": [ { - "name": string, - "class": string, - "type": string, - "ttl": integer, - "data": string + "name": string, + "class": string, + "type": string, + "ttl": integer, + "data": string } ], - "query_time": integer, # in msec - "server": string, - "when": string, - "when_epoch": integer, # naive timestamp if when field is parsable, else null - "when_epoch_utc": integer, # timezone aware timestamp availabe for UTC, else null - "rcvd": integer - "size": string + "query_time": integer, # in msec + "server": string, + "when": string, + "when_epoch": integer, # naive timestamp if when field is parsable, else null + "when_epoch_utc": integer, # timezone aware timestamp availabe for UTC, else null + "rcvd": integer + "size": string } ] Examples: - $ dig cnn.com www.cnn.com @205.251.194.64 | jc --dig -p + $ dig example.com | jc --dig -p [ { - "id": 52172, + "id": 2951, "opcode": "QUERY", "status": "NOERROR", "flags": [ @@ -90,113 +109,35 @@ Examples: "ra" ], "query_num": 1, - "answer_num": 4, + "answer_num": 1, "authority_num": 0, "additional_num": 1, + "opt_pseudosection": { + "edns": { + "version": 0, + "flags": [], + "udp": 4096 + } + }, "question": { - "name": "cnn.com.", + "name": "example.com.", "class": "IN", "type": "A" }, "answer": [ { - "name": "cnn.com.", + "name": "example.com.", "class": "IN", "type": "A", - "ttl": 27, - "data": "151.101.65.67" - }, - { - "name": "cnn.com.", - "class": "IN", - "type": "A", - "ttl": 27, - "data": "151.101.129.67" - }, - { - "name": "cnn.com.", - "class": "IN", - "type": "A", - "ttl": 27, - "data": "151.101.1.67" - }, - { - "name": "cnn.com.", - "class": "IN", - "type": "A", - "ttl": 27, - "data": "151.101.193.67" + "ttl": 39302, + "data": "93.184.216.34" } ], - "query_time": 38, - "server": "2600", - "when": "Tue Mar 30 20:07:59 PDT 2021", - "rcvd": 100, - "when_epoch": 1617160079, - "when_epoch_utc": null - }, - { - "id": 36292, - "opcode": "QUERY", - "status": "NOERROR", - "flags": [ - "qr", - "aa", - "rd" - ], - "query_num": 1, - "answer_num": 1, - "authority_num": 4, - "additional_num": 1, - "question": { - "name": "www.cnn.com.", - "class": "IN", - "type": "A" - }, - "answer": [ - { - "name": "www.cnn.com.", - "class": "IN", - "type": "CNAME", - "ttl": 300, - "data": "turner-tls.map.fastly.net." - } - ], - "authority": [ - { - "name": "cnn.com.", - "class": "IN", - "type": "NS", - "ttl": 3600, - "data": "ns-1086.awsdns-07.org." - }, - { - "name": "cnn.com.", - "class": "IN", - "type": "NS", - "ttl": 3600, - "data": "ns-1630.awsdns-11.co.uk." - }, - { - "name": "cnn.com.", - "class": "IN", - "type": "NS", - "ttl": 3600, - "data": "ns-47.awsdns-05.com." - }, - { - "name": "cnn.com.", - "class": "IN", - "type": "NS", - "ttl": 3600, - "data": "ns-576.awsdns-08.net." - } - ], - "query_time": 27, - "server": "205.251.194.64#53(205.251.194.64)", - "when": "Tue Mar 30 20:07:59 PDT 2021", - "rcvd": 212, - "when_epoch": 1617160079, + "query_time": 49, + "server": "2600:1700:bab0:d40::1#53(2600:1700:bab0:d40::1)", + "when": "Fri Apr 16 16:05:10 PDT 2021", + "rcvd": 56, + "when_epoch": 1618614310, "when_epoch_utc": null } ] @@ -204,7 +145,7 @@ Examples: $ dig cnn.com www.cnn.com @205.251.194.64 | jc --dig -p -r [ { - "id": "23843", + "id": "46052", "opcode": "QUERY", "status": "NOERROR", "flags": [ @@ -213,110 +154,34 @@ Examples: "ra" ], "query_num": "1", - "answer_num": "4", + "answer_num": "1", "authority_num": "0", "additional_num": "1", + "opt_pseudosection": { + "edns": { + "version": "0", + "flags": [], + "udp": "4096" + } + }, "question": { - "name": "cnn.com.", + "name": "example.com.", "class": "IN", "type": "A" }, "answer": [ { - "name": "cnn.com.", + "name": "example.com.", "class": "IN", "type": "A", - "ttl": "30", - "data": "151.101.193.67" - }, - { - "name": "cnn.com.", - "class": "IN", - "type": "A", - "ttl": "30", - "data": "151.101.1.67" - }, - { - "name": "cnn.com.", - "class": "IN", - "type": "A", - "ttl": "30", - "data": "151.101.65.67" - }, - { - "name": "cnn.com.", - "class": "IN", - "type": "A", - "ttl": "30", - "data": "151.101.129.67" + "ttl": "40426", + "data": "93.184.216.34" } ], - "query_time": "24 msec", - "server": "192.168.1.254#53(192.168.1.254)", - "when": "Tue Nov 12 07:16:19 PST 2019", - "rcvd": "100" - }, - { - "id": "8266", - "opcode": "QUERY", - "status": "NOERROR", - "flags": [ - "qr", - "aa", - "rd" - ], - "query_num": "1", - "answer_num": "1", - "authority_num": "4", - "additional_num": "1", - "question": { - "name": "www.cnn.com.", - "class": "IN", - "type": "A" - }, - "answer": [ - { - "name": "www.cnn.com.", - "class": "IN", - "type": "CNAME", - "ttl": "300", - "data": "turner-tls.map.fastly.net." - } - ], - "authority": [ - { - "name": "cnn.com.", - "class": "IN", - "type": "NS", - "ttl": "3600", - "data": "ns-1086.awsdns-07.org." - }, - { - "name": "cnn.com.", - "class": "IN", - "type": "NS", - "ttl": "3600", - "data": "ns-1630.awsdns-11.co.uk." - }, - { - "name": "cnn.com.", - "class": "IN", - "type": "NS", - "ttl": "3600", - "data": "ns-47.awsdns-05.com." - }, - { - "name": "cnn.com.", - "class": "IN", - "type": "NS", - "ttl": "3600", - "data": "ns-576.awsdns-08.net." - } - ], - "query_time": "26 msec", - "server": "205.251.194.64#53(205.251.194.64)", - "when": "Tue Nov 12 07:16:19 PST 2019", - "rcvd": "212" + "query_time": "48 msec", + "server": "2600:1700:bab0:d40::1#53(2600:1700:bab0:d40::1)", + "when": "Fri Apr 16 16:06:12 PDT 2021", + "rcvd": "56" } ] @@ -421,4 +286,4 @@ Returns: ## Parser Information Compatibility: linux, aix, freebsd, darwin -Version 1.7 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 2.0 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/jc/man/jc.1.gz b/jc/man/jc.1.gz index 5767a72b1c34a09bf708bf69786bf80cbb0f575b..9fd9c3c2c2a41591ba0a44b04d19681484b2b327 100644 GIT binary patch literal 2061 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 hJ;XmLu&z 50000000)' +dig example.com | jc --dig ``` ```json -{ - "filename": "docker", - "flags": "-rwxr-xr-x", - "links": 1, - "owner": "root", - "group": "root", - "size": 68677120, - "date": "Aug 14 19:41" -} +[{"id":38052,"opcode":"QUERY","status":"NOERROR","flags":["qr","rd","ra"],"query_num":1,"answer_num":1, +"authority_num":0,"additional_num":1,"opt_pseudosection":{"edns":{"version":0,"flags":[],"udp":4096}},"question": +{"name":"example.com.","class":"IN","type":"A"},"answer":[{"name":"example.com.","class":"IN","type":"A","ttl": +39049,"data":"93.184.216.34"}],"query_time":49,"server":"2600:1700:bab0:d40::1#53(2600:1700:bab0:d40::1)","when": +"Fri Apr 16 16:09:00 PDT 2021","rcvd":56,"when_epoch":1618614540,"when_epoch_utc":null}] +``` +This allows further command-line processing of output with tools like `jq` by piping commands: +```bash +$ dig example.com | jc --dig | jq -r '.[].answer[].data' +93.184.216.34 ``` or using the alternative "magic" syntax: ```bash -jc ls -l /usr/bin | jq '.[] | select(.size > 50000000)' -``` -```json -{ - "filename": "docker", - "flags": "-rwxr-xr-x", - "links": 1, - "owner": "root", - "group": "root", - "size": 68677120, - "date": "Aug 14 19:41" -} +$ jc dig example.com | jq -r '.[].answer[].data' +93.184.216.34 ``` The `jc` parsers can also be used as python modules. In this case the output will be a python dictionary, or list of dictionaries, instead of JSON: ```python ->>> import jc.parsers.ls +>>> import jc.parsers.dig >>> ->>> data='''-rwxr-xr-x 1 root wheel 23648 May 3 22:26 cat -... -rwxr-xr-x 1 root wheel 30016 May 3 22:26 chmod -... -rwxr-xr-x 1 root wheel 29024 May 3 22:26 cp -... -rwxr-xr-x 1 root wheel 375824 May 3 22:26 csh -... -rwxr-xr-x 1 root wheel 28608 May 3 22:26 date -... -rwxr-xr-x 1 root wheel 32000 May 3 22:26 dd -... -rwxr-xr-x 1 root wheel 23392 May 3 22:26 df -... -rwxr-xr-x 1 root wheel 18128 May 3 22:26 echo''' +>>> data = '''; <<>> DiG 9.10.6 <<>> example.com +... ;; global options: +cmd +... ;; Got answer: +... ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64612 +... ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 +... +... ;; OPT PSEUDOSECTION: +... ; EDNS: version: 0, flags:; udp: 4096 +... ;; QUESTION SECTION: +... ;example.com. IN A +... +... ;; ANSWER SECTION: +... example.com. 29658 IN A 93.184.216.34 +... +... ;; Query time: 52 msec +... ;; SERVER: 2600:1700:bab0:d40::1#53(2600:1700:bab0:d40::1) +... ;; WHEN: Fri Apr 16 16:13:00 PDT 2021 +... ;; MSG SIZE rcvd: 56''' >>> ->>> jc.parsers.ls.parse(data) -[{'filename': 'cat', 'flags': '-rwxr-xr-x', 'links': 1, 'owner': 'root', 'group': 'wheel', 'size': 23648, -'date': 'May 3 22:26'}, {'filename': 'chmod', 'flags': '-rwxr-xr-x', 'links': 1, 'owner': 'root', -'group': 'wheel', 'size': 30016, 'date': 'May 3 22:26'}, {'filename': 'cp', 'flags': '-rwxr-xr-x', -'links': 1, 'owner': 'root', 'group': 'wheel', 'size': 29024, 'date': 'May 3 22:26'}, {'filename': 'csh', -'flags': '-rwxr-xr-x', 'links': 1, 'owner': 'root', 'group': 'wheel', 'size': 375824, 'date': 'May 3 -22:26'}, {'filename': 'date', 'flags': '-rwxr-xr-x', 'links': 1, 'owner': 'root', 'group': 'wheel', -'size': 28608, 'date': 'May 3 22:26'}, {'filename': 'dd', 'flags': '-rwxr-xr-x', 'links': 1, 'owner': -'root', 'group': 'wheel', 'size': 32000, 'date': 'May 3 22:26'}, {'filename': 'df', 'flags': -'-rwxr-xr-x', 'links': 1, 'owner': 'root', 'group': 'wheel', 'size': 23392, 'date': 'May 3 22:26'}, -{'filename': 'echo', 'flags': '-rwxr-xr-x', 'links': 1, 'owner': 'root', 'group': 'wheel', 'size': 18128, -'date': 'May 3 22:26'}] +>>> jc.parsers.dig.parse(data) +[{'id': 64612, 'opcode': 'QUERY', 'status': 'NOERROR', 'flags': ['qr', 'rd', 'ra'], 'query_num': 1, 'answer_num': +1, 'authority_num': 0, 'additional_num': 1, 'opt_pseudosection': {'edns': {'version': 0, 'flags': [], 'udp': +4096}}, 'question': {'name': 'example.com.', 'class': 'IN', 'type': 'A'}, 'answer': [{'name': 'example.com.', +'class': 'IN', 'type': 'A', 'ttl': 29658, 'data': '93.184.216.34'}], 'query_time': 52, 'server': +'2600:1700:bab0:d40::1#53(2600:1700:bab0:d40::1)', 'when': 'Fri Apr 16 16:13:00 PDT 2021', 'rcvd': 56, +'when_epoch': 1618614780, 'when_epoch_utc': None}] ``` Two representations of the data are possible. The default representation uses a strict schema per parser and converts known numbers to int/float JSON values. Certain known values of `None` are converted to JSON `null`, known boolean values are converted, and, in some cases, additional semantic context fields are added.