kellyjonbrazil / jc

CLI tool and python library that converts the output of popular command-line tools, file-types, and common strings to JSON, YAML, or Dictionaries. This allows piping of output to tools like jq and simplifying automation scripts.
MIT License
7.9k stars 210 forks source link

Parser Request: "ipconfig /all" (Windows) #594

Open joehacksalot opened 1 month ago

joehacksalot commented 1 month ago

I'm finding myself in need of an ipconfig parser and think this is likely others might find useful. Looking at the output, it looks like it might be rather simple to parse reliably compared to some of the other open parser requests I was looking at.

Here is a sample ipconfig /all for discussion.


   Host Name . . . . . . . . . . . . : ABC-PC1
   Primary Dns Suffix  . . . . . . . : abc.corp
   Node Type . . . . . . . . . . . . : Hybrid
   IP Routing Enabled. . . . . . . . : No
   WINS Proxy Enabled. . . . . . . . : No
   DNS Suffix Search List. . . . . . : abc.corp

Unknown adapter Tailscale:

   Connection-specific DNS Suffix  . :
   Description . . . . . . . . . . . : Tailscale Tunnel
   Physical Address. . . . . . . . . :
   DHCP Enabled. . . . . . . . . . . : No
   Autoconfiguration Enabled . . . . : Yes
   Link-local IPv6 Address . . . . . : fe80::d8ff:5060:f230:9168%5(Preferred)
   Autoconfiguration IPv4 Address. . : 169.254.83.107(Preferred)
   Subnet Mask . . . . . . . . . . . : 255.255.0.0
   Default Gateway . . . . . . . . . :
   DNS Servers . . . . . . . . . . . : fec0:0:0:ffff::1%1
                                       fec0:0:0:ffff::2%1
                                       fec0:0:0:ffff::3%1
   NetBIOS over Tcpip. . . . . . . . : Disabled

Ethernet adapter Ethernet0:

   Connection-specific DNS Suffix  . :
   Description . . . . . . . . . . . : Intel(R) 82574L Gigabit Network Connection
   Physical Address. . . . . . . . . : 00-0C-2A-0A-7A-D4
   DHCP Enabled. . . . . . . . . . . : Yes
   Autoconfiguration Enabled . . . . : Yes
   Link-local IPv6 Address . . . . . : fe80::47ac:e226:3b46:a740%7(Preferred)
   IPv4 Address. . . . . . . . . . . : 192.168.22.108(Preferred)
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Lease Obtained. . . . . . . . . . : Tuesday, June 11, 2024 12:19:26 PM
   Lease Expires . . . . . . . . . . : Friday, September 20, 2024 4:25:16 AM
   Default Gateway . . . . . . . . . : 192.168.22.1
   DHCP Server . . . . . . . . . . . : 192.168.22.1
   DHCPv6 IAID . . . . . . . . . . . : 100634309
   DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-29-4D-7E-49-00-0A-22-08-24-BD
   DNS Servers . . . . . . . . . . . : 192.168.22.151
   NetBIOS over Tcpip. . . . . . . . : Enabled
kellyjonbrazil commented 1 month ago

This was also asked for in https://github.com/kellyjonbrazil/jc/issues/464

I would welcome a PR for and ipconfig /all parser.

joehacksalot commented 1 month ago

This was also asked for in #464

You're right. My bad. I was looking at issue titles and didn't see that. Let me take a look at what it'll take making a parser. Haven't done one before, and the first couple I looked at looked rather complex. If I put something together, I'll submit a PR. I do worry I don't have all the possible output for ipconfig and might miss something.

joehacksalot commented 1 month ago

I've got the parser working outside of jc and working to tie it in. I'm struggling to understand the purpose/use of raw output. I tried looking at several other parsers and couldn't make sense of it either. Any help here would be appreciated!

Edit: Disregard. I got it.

kellyjonbrazil commented 1 month ago

Just for others who may read this thread - there are typically two parsing stages: parse() and process()

parse() should do most of the heavy lifting and get data in the schema but without doing any type conversions.

process() should iterate over the dict or list object from parse() and do the string-to-x conversions as necessary. Sometimes other fields are added here, like calculated timestamps, splitting measurement and unit fields, etc. This second stage ensures that the output matches the documented schema.

Not all parsers will have anything going on in the process() function. These are typically very simple parsers.

Many parsers have both stages and the user can skip the process() stage by using the --raw cli option or the raw=True python parameter. This can be useful if the user needs the more literal string output or if they are troubleshooting a parser issue and want to workaround or narrow down where the issue is by skipping the process() stage.

kellyjonbrazil commented 3 weeks ago

I have merged this into dev and it will make it into the next release.