Right now we have a standardized structure for cond mode scripts, but op mode script structure is still arbitrary—just like in the pre-1.2 days.
Introduction of an HTTP API makes this especially problematic.
There are many "can't do it" things coming from this issue:
- Can't get op mode command output in a machine-readable format
- Can't run a command by its path outside of the CLI
- Can't test individual op mode functions
One good thing about op mode is that, oddly, it's not a part of vyatta-cfg. Thus it's much easier to strangle since it can be re-done without any effects on the configuration subsystem. The only question is how exactly we are going to do it.
I've been long thinking how op mode should be incorporated in vyconf. Now I'm thinking maybe it shouldn't. It's really outside of the configuration system and appears to be an unrelated concern.
What can we do instead? We can create a separate op mode daemon in Python that will serve op mode requests. One observation is that op mode paths are a lot like HTTP application routes. For example, show interfaces ethernet eth0 detail maps is expressible in most web framework routing terms, like /show/interfaces/ethernet/<intf>/detail.
They do allow registering different routes for /show/interfaces/ethernet/ and /show/interfaces/ethernet/<intf>, which would solve our issue with messy tag/non-tag nodes.
- vyos-opd walks through op mode script dir on startup, loads every module
- upon loading, modules register one or more op mode routes
- vyos-opd starts serving requests for op mode paths
It likely should serve requests over a ZMQ socket for better performance. We need to discuss wether translating a CLI path like show interfaces to URL encoding for the routing library should happen on the client or daemon side of the request.
Op mode module structure
A module must define one or mode op mode functions. For example, a module for show system uptime will likely define just one show_uptime Python function.
Modules for complex components like interfaces or IPsec may provide many more functions.
They must also have an entry point function that registers routes for each function.
Standard request arguments
- brief — output only essential information
- detail — output detailed information
- "normal" — implied if neither a brief nor detail flags are set
Op mode functions may ignore the verbosity argument. For some functions, like show system uptime, different verbosity levels really make no sense.
- json — output JSON
- text — output human-readable plain text
These arguments should be composable with all other. For example json | brief combination would output JSON with some fields omitted (compared to "normal" or "detail") levels.
This is a rough draft that needs refinement of course.