# Loads plugins from both /path/to/dir1 and /path/to/dir2 $ KUBECTL_PLUGINS_PATH=/path/to/dir1:/path/to/dir2 kubectl plugin -h
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. |
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.
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.
The plug-in loader uses the following search order:
${KUBECTL_PLUGINS_PATH}
If specified, the search stops here.
If the KUBECTL_PLUGINS_PATH
environment variable is present, the loader uses
it as the only location to look for plug-ins. The KUBECTL_PLUGINS_PATH
environment variable is a list of directories. In Linux and Mac, the list is
colon-delimited. In Windows, the list is semicolon-delimited.
If KUBECTL_PLUGINS_PATH
is not present, the loader begins to search the
additional locations.
${XDG_DATA_DIRS}/kubectl/plugins
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_DIRS
environment variable. The plug-in loader searches the
kubectl/plugins directory inside of directories specified by the
XDG_DATA_DIRS
environment variable. If XDG_DATA_DIRS
is not specified, it
defaults to /usr/local/share:/usr/share.
~/.kube/plugins
The plugins
directory 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
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 echo
,
sed
, or grep
. Alternatively, it could rely on the oc
binary.
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.
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.
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
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
oc
commands.
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 oc
binary 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 oc
and 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 --namespace
global 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_DESCRIPTOR_NAME
, KUBECTL_PLUGINS_DESCRIPTOR_COMMAND
.
KUBECTL_PLUGINS_GLOBAL_FLAG_*
: One environment variable for every global flag
supported by oc
. For example, KUBECTL_PLUGINS_GLOBAL_FLAG_NAMESPACE
,
KUBECTL_PLUGINS_GLOBAL_FLAG_LOGLEVEL
.
KUBECTL_PLUGINS_LOCAL_FLAG_*
: One environment variable for every local flag
declared in the plugin.yaml descriptor. For example,
KUBECTL_PLUGINS_LOCAL_FLAG_HEAT
in the preceding great-plugin
example.