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 >= 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-utils and 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.


We designed 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. --log-level or --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).

opsi-cli --help


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 auto, json, pretty-json, msgpack, table and csv. As payload and logging are sent to different streams, multiple opsi-cli calls can be chained (output to input) by using pipes.

opsi-cli --help

How to get started

opsi-cli is contained in opsi-utils >= 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 (--service, --username, --password) or by storing the credentials on the client side (see opsi-cli config service add --help).


Currently 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.