Pipes in VyOS CLI
Unix pipes are an indispensable tool on a sysadmin’s belt. Eventually, it becomes second nature to build a pipeline of several tools to transform data and one often feels frustrated when they can’t use it in a CLI environment distinct from a Unix shell.
VyOS CLI is a high-level, centralized interface where the great variety of configurable subcommands often eschews the need to pipe multiple small programs together to shape the output into the desired form. (Although, you still can do that, naturally.) However, there are cases where one feels the need of generic functions that can be applied to the output of any subcommand.
You might be surprised to hear that VyOS CLI does, in fact, come with its own pipe functionality and a smart one at that. Instead of distinct programs, VyOS CLI provides pipe functions that are explicitly intended for this purpose. Such functions can be tab-completed and the CLI will only suggest pipe functions that would make sense in the context of the preceding command. This functionality is, unfortunately, not very well known, as the subcommands tend to cover most cases, but once you see how convenient pipe functions are, you’ll find yourself writing your own to cover your project’s needs.
Let’s cut to the chase and illustrate pipes with a few examples, starting with the simplest, yet most commonly used functions, then move on to more complex ones.
more
and no-more
more
displays the piped text in a pager for reading, whereas no-more
overrides the subcommand’s default behaviour of using a pager by directly printing the output.
match
and no-match
As the name suggests, match
, put simply, matches text from piped input according to the specified regular expression pattern. no-match
does the opposite, discarding matching lines. These pipe functions use POSIX extended regular expressions by default.
# show firewall | match ipv6 ipv6-receive-redirects disable ipv6-src-route disable
count
count
simply prints the number of lines in the piped input and discards the text itself. Naturally, you can chain all pipe functions.
$ show conntrack table ipv4 | match udp | count 160
Moving on...
strip-private
Sometimes, you need to save the output of a command in a publicly accessed place or share it with others who don’t have the credentials to see parts of the output containing sensitive information. Instead of manually going through the output line by line, trying to spot confidential data to scrub each time, you can just use the strip-private
function to sterilise the text. We’re going to use it in the next examples.
$ show arp | match '.101.' | match 'eth3' | strip-private xxx.xxx.101.79 ether XX:XX:XX:XX:XX:36 C eth3 xxx.xxx.101.254 ether XX:XX:XX:XX:XX:60 C eth3
The following two functions can only be used in conf mode, as they don’t make sense in an op mode context. Don’t forget to commit your changes before using them, although they will warn you either way.
commands
You might often find yourself trying to replicate an existing configuration. Instead of directly fiddling with config files or manually writing out op mode commands from conf mode output, you can ask the CLI to convert the config to op mode commands.
Consider the following configuration:
# show protocols bgp | strip-private bgp XXXXXX { address-family { ipv4-unicast { network xxx.xxx.16.0/21 { } } } neighbor xxx.xxx.34.1 { address-family { ipv4-unicast { route-map { export LocalOnly } } } remote-as XXXXXX } }
To obtain the commands that produced this config, we can simply use commands
:
# show protocols bgp | commands | strip-private set bgp XXXXXX address-family ipv4-unicast network xxx.xxx.16.0/21 set bgp XXXXXX neighbor xxx.xxx.34.1 address-family ipv4-unicast route-map export 'LocalOnly' set bgp XXXXXX neighbor xxx.xxx.34.1 remote-as '64840'
json
The HTTP API takes configuration in the form of JSON payloads. To make it easier to prepare JSON data, json
converts Unix-style config syntax into JSON. Note that this pipe function is going to be included in the upcoming release, although it’s considered for a backport as of v1.2.6. You can try it in the current rolling release.
Again, consider the following configuration.
# show system syslog global { facility all { level info } facility protocols { level debug } }
It's trivial to convert it to JSON as such.
# show system syslog | json { "global": { "facility": { "all": { "level": "info" }, "protocols": { "level": "debug" } } } }
Of course, you can also use JSON processors like jq
with it.
# show system syslog | json | jq '.global.facility.all.level' "info"
That wraps up the pipe functions currently in VyOS CLI. I hope you’ll find them useful.
Comments