opsi-cli: Introduction to the new opsi command line interface
At the opsiconf opsiconf 2022, we announced a new command line tool to work with opsi environments. We also offered a quick preview of the new tool.
opsi-cli is now available as part of
opsi-utils >= 184.108.40.206 and as opsi package in our public repositories at download.uib.de. It can be used to access backend functions of an opsi config server via RPC and is highly customizable.
In this blog post, I shall give a short introduction to the new
opsi-cli. I will also write about the motivation, the design concept, and our implementation. At the end of the article, you can find installation instructions.
Currently there are a plethora of command line tools to interact with opsi. The various components of
opsi-python scripts each have their own command line options, structure, output formats and design paradigms.
opsi-python scripts make use of python libraries installed in the underlying operating system and are therefore dependent on those. Some backend operations use the RPC interface, while others work around the opsiconfd to directly access the underlying data structures.
With all this in mind, the goal was to design a tool which gives access to the same functions (and more!) while also keeping a coherent and robust scheme. Also, backend functions should be more easily accessible while maintaining user-based access restrictions.
opsi-cli to fulfill the following requirements
- Consistent form of options, parameters, inputs and outputs
- Compact binary executables for linux, macOS and Windows
- Dynamically extensible via custom python plugins
- Interaction with opsiconfd via RPC Interface only
- Proper distinguishing between payload (to stdout) and logging/errors/debugoutput (to stderr)
Step by step, we intend to implement parts of
opsi-utils (and more) as commands in
opsi-cli and keep the
opsi-utils commands as wrappers calling
opsi-cli behind the scenes, to maintain backwards compatibility.
opsi-cli is structured to have multiple levels of commands and sub-commands, as inspired by the
docker command line interface for instance. The general endpoint
opsi-cli has multiple commands (or groups), each of which have sub-commands. The entry point as well as the commands and sub-commands can each have options affecting everything hierarchically below them. That means that an option set for a sub-command affects only the sub-command itself, while an option set for a command (group) affects all sub-commands of that command. Options set at entry point level affect all commands (e.g.
--output-format). The option
--help exists on every level and can be used to show details about the available options and/or sub-commands at that point.
opsi-cli is intended to fulfill one specific task and then exit with a meaningful exit code (not to be run as service).
We decided to implement
opsi-cli in python, using the module click (or rich_click for beautiful colored outputs). The core of
opsi-cli is a binary that contains the basic commands config, self and plugin as well as some more specialized ones.
The configuration can hold access data for multiple opsi config servers (url, username and password) which are used to access backend methods. If no credentials are supplied,
opsi-cli tries to connect to https://localhost:4447 with credentials extracted from a local backend (which will only work if
opsi-cli is run directly on the config server).
There is a system- and a user-specific directory for plugins which are loaded dynamically at run-time. Those plugins can be imported, exported and exchanged between instances of opsi-cli. For zsh, bash and fish (and probably for powershell at some point in the future) there is an autocompletion feature (by pressing [Tab] / [Tab] [Tab]) which can be installed for more comfortable handling.
opsi-cli can output data in different ways, depending on the entry point level option
--output-format. This way output can be optimized for human readability or efficiency in compression/transmission. Available formats are currently
csv. As payload and logging are sent to different streams, multiple
opsi-cli calls can be chained (output to input) by using pipes.
How to get started
opsi-cli is contained in
opsi-utils >= 220.127.116.11. That means once you upgrade
opsi-utils on your config server to any of these versions,
opsi-cli will already be available. As there is a local backend from which credentials can be extracted (provided the calling user has the required permissions),
opsi-cli can be used without supplying any additional service and user information.
To use opsi-cli on a different host (like a Windows machine), the easiest way to get it is to use the opsi package
opsi-cli from our public repositories at download.uib.de. For access to an opsi service, credentials must be supplied to opsi-cli either by entry point level options (
--password) or by storing the credentials on the client side (see
opsi-cli config service add --help).
opsi-cli is in a proposal state. At the moment we do not guarantee stability of the interface. It may very well be necessary for us to introduce breaking changes in the way
opsi-cli works. The plugin format and handling especially may be subject to change. Obviously we try to avoid breaking things, but sometimes it is better to correct design flaws early instead of carrying them through as legacy code.
Have fun playing around with opsi-cli, feel free to explore the new possibilities and please contact us if you have suggestions or feedback.