-
Notifications
You must be signed in to change notification settings - Fork 1
Plugins
A plugin is a separate process, which get loaded by the core binary. The plugin interacts with some entity & sends the result back to the core binary.
All plugins are installed at $HOME/.devops/plugins/<plugin-name>
Plugins are written independent of the core binary. There internal working varies upon the implementation & they just have to satisfy the GRPC contract to make it work with core binary. So a plugin may or may not have a configuration option.
Devops CLI has created some terminolgies to make it easier to work with plugins & UI. Below is the list of them.
-
Resource Types These are the resource a system exposes or uses.
For example:
- Kubernetes has (Pods, Configmaps, Deployments etc...)
- Helm has (Charts, Releases, Repositories etc...)
- Gitlab has (Pipelines etc...)
-
Resource These are instances of a resource.
-
Isolators (Grouping of resource types) Every resource type is isolated using some kind of constraint. Regardless, a plugin may or may not have isolators.
For example:
- Kubernetes has
Namespaces
- Helm has
Namespaces
- AWS has
regions
- Kubernetes has
-
Normal Actions (CRUD) These are the basic CRUD operations that can be performed on a resources. End user does not have any control on this operation. It upto the implementator of plugin on what operation he supports.
-
Specific Actions Every resource an have a specific action. A specific action is some kind of operation that can be only performed on that resource
For example:
- Kubernetes has (describe on pods, shell on pods etc...)
- Helm has (viewing values of a release, viewing resources installed by a release)
End user can customize according to their need. We see this in more detail next.
In the above image, you can see resources
is a table. The rows & columns of this table is customizable. And this is done via configuration file that exists at $HOME/.devops/plugins/<plugin-name>/resource_config/<resource-name>.yaml
.
Note: The existence of this configuration file. Is dependent on plugin implementation. It may or may not exits for all plugins.
Example Configuration:
operations:
- name: "namespace"
json_paths:
- path: "metadata.namespace"
output_format: ""
- name: "name"
json_paths:
- path: "metadata.name"
output_format: ""
- name: "status"
json_paths:
- path: "status.phase"
output_format: ""
- name: "age"
json_paths:
- path: "metadata.creationTimestamp|@age"
output_format: ""
styles:
- row_background_color: mediumpurple
conditions:
- 'status.phase == "Terminating"'
- row_background_color: lightskyblue
conditions:
- 'status.phase == "Active"'
- row_background_color: lightskyblue
conditions:
- 'status.phase == "NA"'
Working
Let's say for a given resource, The above is the configuration. This will render a table with columns namespaces, name, status, age
. And the values of each resource will be extracted from the resource JSON object (NOTE: A resource read from a plugin, is expected to be in object type).
Under the hood we use this library to extract values from the JSON object. As per the key specified in json_paths.[*].path Library.
The output_format
field specifies how to render the column value. It is equivalent to many programming language printf() statements. You specify formatters like %s-some-test/%s
. The %s will be replaces by value from the evaluation of json_paths.[*].path. Note the number of formatters should be equal to number of json_paths array. By default if no formatter is specified, The value of json_paths evaluation will be overriden. And only the last value will be taken.
The styles
field is used to specify the row color to be rendered. The default color is skyblue. The row color can be rendered upon various conditions. These conditions are similar to what you write in if-else statement in programming languages. Entire JSON object of the resource under operation is available for evaluation of condition.
Under the hood we use the following library for evaluation conditions Library.
As I said end user can customize these action according to their need.
Every specific action executes a script provided by user. This config can be found in the same resource configuration file. The unique thing about these scripts is that, The value of the current resource is available via templating. Meaning before executing the actual script. A template is executed, which has access to entire resource object under operation. The result of template execution is a final script. That will be executed.
We use Golang templates under the hood.
- name: "describe"
key_binding: "d"
execution:
cmd: |
#!/bin/bash
kubectl describe {{.resourceType}} {{.resourceName}} -n {{.isolatorName}} --kubeconfig {{.authPath}} --context {{.authName}}
output_type: "string"
The output_type
field can be of 4 types:
-
nothing This is used, When the stdout output of script is not of any value, But the actual execution is. For example: Kubernetes Port Forward
-
string This is used, When the stdout output of script has to be seen, when it is executed.
NOTE: The script cannot be a long running process here. If it is a long running script, the server will get stuck till the script is complete & wait for it to return string result.
-
stream This is used, When the stdout output of script has to be seen & it output is generated continuously endlessly, when it is executed. For example: Viewing Live Logs of Application / Kubernetes Pods Logs
-
bidirectional This is used, When you not only have to view the output, but also interact with via stdin (give input). For example: SSH into node / Getting shell of kubernetes pod
resourceType = Current resource type under operation
resourceName = Current resource name under operation
isolatorName = Current isolator name under operation
authPath = Path to the plugin specific authentication file
authName = Context/Profile name in that authentication file
resource = entire resource object
Interacts with Kubernetes API
Example k8s plugin configuration, You can find/create the configuration file at $HOME/.devops/plugins/kubernetes/config.yaml
kube_configs:
# Human readable name to identify the kubeconfig file in UI.
- name: aws-dev-cluster
# The path to the kubeconfig file, It should be an absolute path
path: "/home/sharad/dev2.kubeconfig"
contexts:
# All the contexts in the given kube-config file will be automatically loaded.
# But if you want to change certain supported settings for a context, such as the below one. You can specify the context name & specific fields to override the settings
- name: "default"
# The following namespace will be shown by default, when devops-cli connects to this cluster
default_namespaces_to_show:
- "default"
- "dev"
- By default, when the plugin starts. It loads the default kube-config file found at
$HOME/.kube/config
& all the contexts in it. - This plugin does not use environment variables or command line flags to load authentication credentials.
- Authentication is managed via files & files only, to connect to a K8s cluster. You need to specify path to the valid kube config file.
- To use kube-config files other than the default location. You can update
config.yaml
of the plugin & specify the path to the kube-config file. See the above example config.