Response: CLI Is an API
Andrew Yourtchenko and Dr. Tony Przygienda left wonderful comments to my Screen Scraping in 2025 blog post, but unfortunately they prefer commenting on a closed platform with ephemeral content; the only way to make their thoughts available to a wider audience is by reposting them. Andrew first:
I keep saying CLI is an API. However, it is much simpler and an easier way to adapt to the changes, if these three conditions are met:
- regexes are written in a defensive, yet permissive fashion (generously ignore the spaces and lines that do not match, but make sure you ignore both spaces and tabs)
- for the data that you do capture, be very conservative, such that your likely outcome if something goes awry is no data rather than garbage data.
- handle all the parsed data as Option enum in a language which allows for that and always check whether it is Some(value) or None before using it.
The (3) you will have to do anyway even with structured API, when handling the changes. For the (1) and (2), if (in some mythical universe), vendors were to publish the regexes, it will be indistinguishable from the other transports. (I am of course leaving aside the question of data conversions, because they are equally a problem when using the “structured” APIs as well, just of a different shape.
It looks like Cisco (having to deal with ancient codebase with printf statements sprinkled all over it) did something like what Andrew suggested at least once (pyATS/Genie) if not twice (ConfD on Cisco IOS/XE).
Not surprisingly, Tony disagreed (probably based on his battle scars):
Sorry, it’s largely putting lipstick on you know what. It’s impossible to know as a vendor what kind of “smart regexes” some customer put in that can deal with “any change” until they can’t. Because whatever the “smart regex” is it is still something that does fundamentally not understand the semantic structure of the underlying output. And having dealt with some of it it’s about the third circle of hell to maintain such “super smart regexes” with backtracking and whatever else not …
I have to agree with Tony: regexes suck, and I always prefer to work with structured data… if only the vendors wouldn’t make it so cumbersome that it’s easier to deal with the pain of screen-scraping.
I've been enjoying this series so much. This topic is coming up so much lately. I hope we can get some sensible path forward.
At least projects like ntc-templates and ttp-templates make regex a little more tolerable to work with on network devices.
Interesting post as always from Mr. Ivan.
Another twist on this subject.
For years you hear about how network professionals must become programmers(for hyped AI to replace anyway) and learn programming languages for their jobs so they can build automation tools etc. Yet it seems the industry misses the fact(or they hid /re-cast it on purpose to sell some new “product”) that the CLI is and has been the network engineers programming language and indirect API since the start. The network CLI has programming constructs like verbs and literals, variables(ip address under an interface etc) and functions/methods like BGP or OSPF process and each interface is a “function” you program the function(assign the IP) enable it and it runs in its loop as UP/UP until another condition. Access lists, PBR, static routes(go to) alias statements, event manager applets, etc are all programmatic language like with structures in the CLI that you carefully have to plan and test just like any other coding project. There are probably more accurate analogies to what I am expressing her but you get the ‘gist’ of it.
So this post regarding the CLI is an API and screen scraping is probably still easier is interesting.
So now the vendors build these APIs that use what? CLI – NXOS for example where you have python accessible API using what, CLI commands.
or using the NX API sandbox and what method do you start out with is the NXAPI-CLI nice rhyme to it "jsonrpc": "2.0", "method": "cli", "params": { "cmd": "show interface", "version": 1
Or under Python Import cisco cisco.cli('show hostname') cisco.cli("config t") cisco.cli("interface vlan2") cisco.cli("ip address", ipadd) cisco.cli("end") cisco.cli("show interface vlan2")
… but hey - sarcasm - “ it is the dreadful cli” and those “cli jockeys” vendors have been selling to get us off of for decades.…….
hmm so why use the CLI “constructs” in python, ansible and xCONF and rest API access methods accessing the same CLI directly via the OS’s key/value XML, JSON and YAML data serialization and YANG constructs of cli structure command verbs.
Why not rid the industry of the sarcasm - “dreadful cli”- and build closed network OS with only a GUI and API that can only be controlled by the GUI operator(human) and automated or controlled/orchestrated by an API with commands that are only closed coded rest, python etc and sent to the device. There is no line by line interface for the user to directly enter commands immediate feedback via a keyboard.
But it seems the great and powerful CLI language is the language for most of the other tools(and screen scrapers) to utilize. The only issue industrywide was there was no standard CLI due to multivendor and patent considerations vs some standards present for C and python etc.
Will the open user presented CLI survive or will vendors make their solutions purely closed box(no serial console), only interfaced via a GUI or through an API(eventually AI agent) that uses programming verbs(not human typed commands) you cannot execute yourself, unless of course someone strings the closed API’s verbs together in the form of (hmm alias commands) for you and presents them in the GUI app so what you type in the GUI app’s “command line” prompt is then sent via API to the devices and guess what?,,, we just re-invented an off box cli and back to the beginning 😉 Oh brother ahh just leave the CLI alone and keep it.
pyATS/Genie is a good example on why you shouldn't parse CLI with regexes, notably "liberal" ones. You are likely to extract incorrect information. I have written about that a few years back and I believe this is still correct today: https://vincent.bernat.ch/en/blog/2021-pyats-genie-parser.
Thanks a million for the feedback. One would hope that regex parsers coming from a vendor would be better tested and I would definitely just match up/down states in your example, not the end-of-line. OTOH I have to admit I never saw that VRF exception you mentioned in your blog post in my life.