Chapter 7. Extending the CLI
This topic reviews how to install and write extensions for the CLI. Usually called plug-ins or binary extensions, this feature allows you to extend the default set of
oc commands available and, therefore, allows you to perform new tasks.
A plug-in is a set of files: typically at least one plugin.yaml descriptor and one or more binary, script, or assets files.
CLI plug-ins are currently only available under the
oc plugin subcommand.
CLI plug-ins are currently a Technology Preview feature. Technology Preview features are not supported with Red Hat production service level agreements (SLAs), might not be functionally complete, and Red Hat does not recommend to use them for production. These features provide early access to upcoming product features, enabling customers to test functionality and provide feedback during the development process.
See the Red Hat Technology Preview features support scope for more information.
You must have:
7.3. Installing Plug-ins
Copy the plug-in’s plugin.yaml descriptor, binaries, scripts, and assets files to one of the locations in the file system where
oc searches for plug-ins.
Currently, OpenShift Container Platform does not provide a package manager for plug-ins. Therefore, it is your responsibility to place the plug-in files in the correct location. It is recommended that each plug-in is located on its own directory.
To install a plug-in that is distributed as a compressed file, extract it to one of the locations specified in The Plug-in Loader section.
7.3.1. The Plug-in Loader
The plug-in loader is responsible for searching plug-in files, and checking if the plug-in provides the minimum amount of information required for it to run. Files placed in the correct location that do not provide the minimum amount of information (for example, an incomplete plugin.yaml descriptor) are ignored.
188.8.131.52. Search Order
The plug-in loader uses the following search order:
If specified, the search stops here.
KUBECTL_PLUGINS_PATHenvironment variable is present, the loader uses it as the only location to look for plug-ins. The
KUBECTL_PLUGINS_PATHenvironment variable is a list of directories. In Linux and Mac, the list is colon-delimited. In Windows, the list is semicolon-delimited.
KUBECTL_PLUGINS_PATHis not present, the loader begins to search the additional locations.
The plug-in loader searches one or more directories specified according to the XDG System Directory Structure specification.
Specifically, the loader locates the directories specified by the
XDG_DATA_DIRSenvironment variable. The plug-in loader searches the kubectl/plugins directory inside of directories specified by the
XDG_DATA_DIRSenvironment variable. If
XDG_DATA_DIRSis not specified, it defaults to /usr/local/share:/usr/share.
pluginsdirectory under the user’s kubeconfig directory. In most cases, this is ~/.kube/plugins:
# Loads plugins from both /path/to/dir1 and /path/to/dir2 $ KUBECTL_PLUGINS_PATH=/path/to/dir1:/path/to/dir2 kubectl plugin -h
7.4. Writing Plug-ins
You can write a plug-in in any programming language or script that allows you to write CLI commands. A plug-in does not necessarily need to have a binary component. It could rely entirely on operating system utilities like
grep. Alternatively, it could rely on the
The only strong requirement for an
oc plug-in is the plugin.yaml descriptor file. This file is responsible for declaring at least the minimum attributes required to register a plug-in and must be located under one of the locations specified in the Search Order section.
7.4.1. The plugin.yaml Descriptor
The descriptor file supports the following attributes:
name: "great-plugin" # REQUIRED: the plug-in command name, to be invoked under 'kubectl' shortDesc: "great-plugin plug-in" # REQUIRED: the command short description, for help longDesc: "" # the command long description, for help example: "" # command example(s), for help command: "./example" # REQUIRED: the command, binary, or script to invoke when running the plug-in flags: # flags supported by the plug-in - name: "flag-name" # REQUIRED for each flag: flag name shorthand: "f" # short version of the flag name desc: "example flag" # REQUIRED for each flag: flag description defValue: "extreme" # default value of the flag tree: # allows the declaration of subcommands - ... # subcommands support the same set of attributes
The preceding descriptor declares the
great-plugin plug-in, which has one flag named
-f | --flag-name. It could be invoked as:
$ oc plugin great-plugin -f value
When the plug-in is invoked, it calls the
example binary or script, which is located in the same directory as the descriptor file, passing a number of arguments and environment variables. The Accessing Runtime Attributes section describes how the
example command accesses the flag value and other runtime context.
7.4.2. Recommended Directory Structure
It is recommended that each plug-in has its own subdirectory in the file system, preferably with the same name as the plug-in command. The directory must contain the plugin.yaml descriptor and any binary, script, asset, or other dependency it might require.
For example, the directory structure for the
great-plugin plug-in could look like this:
~/.kube/plugins/ └── great-plugin ├── plugin.yaml └── example
7.4.3. Accessing Runtime Attributes
In most use cases, the binary or script file you write to support the plug-in must have access to some contextual information provided by the plug-in framework. For example, if you declared flags in the descriptor file, your plug-in must have access to the user-provided flag values at runtime.
The same is true for global flags. The plug-in framework is responsible for doing that, so plug-in writers do not need to worry about parsing arguments. This also ensures the best level of consistency between plug-ins and regular
Plug-ins have access to runtime context attributes through environment variables. To access the value provided through a flag, for example, look for the value of the proper environment variable using the appropriate function call for your binary or script.
The supported environment variables are:
KUBECTL_PLUGINS_CALLER: The full path to the
ocbinary that was used in the current command invocation. As a plug-in writer, you do not have to implement logic to authenticate and access the Kubernetes API. Instead, you can use the value provided by this environment variable to invoke
ocand obtain the information you need, using for example
oc get --raw=/apis.
KUBECTL_PLUGINS_CURRENT_NAMESPACE: The current namespace that is the context for this call. This is the actual namespace to be considered in namespaced operations, meaning it was already processed in terms of the precedence between what was provided through the kubeconfig, the
--namespaceglobal flag, environment variables, and so on.
KUBECTL_PLUGINS_DESCRIPTOR_*: One environment variable for every attribute declared in the plugin.yaml descriptor. For example,
KUBECTL_PLUGINS_GLOBAL_FLAG_*: One environment variable for every global flag supported by
oc. For example,
KUBECTL_PLUGINS_LOCAL_FLAG_*: One environment variable for every local flag declared in the plugin.yaml descriptor. For example,
KUBECTL_PLUGINS_LOCAL_FLAG_HEATin the preceding