Actions
Actions are scripts written in bash or python that are configured with a json
file. These scripts can be used to automate your workflow - removing the need to memorize common commands. Actions are located on the filesystem at ~/Library/Application\ Support/Kubermagic/Actions
, which can be opened in Kubermagic through the menu bar: Actions: Show in Finder
.
A basic action is just a directory with either a main.bash
/main.py
file and config.json
.
Organization and Grouping
Actions can be organized using subdirectories in the filesystem. To group actions together, simply place the actions directories together in a parent directory. Action groups can be grouped together into further subgroups.
Shell Actions
Shell actions are created by adding a main.*
script to an action directory (main.sh
, main.fish
, or main.py
for example). A shell script must have a shebang to point the script interpreter. Shell scripts are useful for saving commonly used kubectl
commands. The output can be sent to the terminal, or can open up a new terminal session. Some examples are included to get in idea of the potential of shell actions.
Environment variables
Environment variables need to be declared within Kubermagic as scripts run in an independant shell environment and will not inherit environment variables like $PATH. Custom environment variables can be set for use within actions in Kubermagic: Preferences: Advanced
. Actions must declare which environment variables will be needed with the environment_variables
config file setting.
The script automatically recieves the following environment variables:
KUBECTL
The location of the application's built-in version of kubectl.
CONTEXT
The currently active context.
NAMESPACE
The currently selected namespace.
POD
, CONTAINER
, DEPLOYMENT
, SERVICE
, ENDPOINT
, CRONJOB
, JOB
, PERSISTENTVOLUME
, CONFIGMAP
, SECRET
, EVENT
Depending on the scope, the selected pod, deployment, etc.. is passed as an environment variable. (Both POD
and CONTAINER
will be set if setting scope
is set to container
)
Running shell commands
Shell scripts runs in their own shell environment, so will need explicit locations to binaries if using other shell commands.
Smart Actions
Basic Structure
Kubermagic includes Python 3.7 that allows for advanced, interactive scripting. For Kubermagic to recognize an action as a smart action, the setting is_smart_action
must be set to true in config.json
. A Kubermagic smart action has the following components:
```python hl_lines="1 3 7"
from kubermagic import KubermagicAction # 1
class Action(KubermagicAction): # 2
def run(self):
print("Hello, world!")
if name == "main": # 3
a = Action()
a.test_run()
```
-
A
kubermagic
library is available for scripts run from kubermagic. -
Each action must have a class titled
Action
that inherits fromKubermagicAction
. Therun()
method will be called on invocation. -
(Optional) To test the script locally without having to go through the app, a
test_run()
method is included. (Add/<path to app>/Kubermagic.app/Contents/Resources/python3.7/lib/site-packages
to sys.path to test locally.)
Action Methods
There are a handful of API methods that allow for interacting with Kubermagic. Due to how the Kubermagic interacts with the python interpreter, the following methods suspend script execution while the dialog/panel waits for user input. The script resumes at the callback method passing in the user input as a parameter.
```python hl_lines="5 6 7 8 9 11"
from kubermagic import KubermagicAction
class Action(KubermagicAction):
def run(self):
self.ok_cancel_dialog(
title="Title",
dialog_text="This is the OK/Cancel dialog text.",
callback=self.ok_callback
)
def ok_callback(self, ok_clicked):
if ok_clicked:
print("OK Button Pressed")
else:
print("Cancel Button Pressed")
```
kubermagic.KubermagicAction methods
notification()
.notification(self, title, subtitle="", informative_text="", callback=None)
Display a notification center alert.
ok_dialog()
.ok_dialog(self, title, dialog_text, ok_button_text=None, callback=None)
Display a panel with a button.
ok_cancel_dialog()
.ok_cancel_dialog(self, title, dialog_text, ok_button_text="OK", cancel_button_text="Cancel", callback=None)
Display a panel with a two buttons.
form_dialog()
.form_dialog(self, title, dialog_text, form, ok_button_text="OK", cancel_button_text="Cancel", callback=None)
Display a panel with a form. (See below)
Forms
Forms are a powerful feature of Kubermagic that provides interactive actions. Let's jump into an example:
```python hl_lines="1 8 9 10 11 16 17 18 19 20 22"
from kubermagic import KubermagicAction, forms # 1
GREETING_CHOICES = (
'Hello',
'Goodbye',
)
class GreetingForm(forms.Form): # 2
name = forms.TextField(placeholder="Your name")
greeting = forms.DropdownField(choices=GREETING_CHOICES)
is_exclamation = forms.CheckboxField(label="Add Exclamation", checked=False)
class Action(KubermagicAction):
def run(self):
form = GreetingForm() # 3
self.form_dialog(
"Greeting Form", "Please select how you would like to be greeted.",
form, ok_button_text="Greet me", callback=self.greet_callback
)
def greet_callback(self, form_data): # 4
greeting = form_data["greeting"]
name = form_data["name"]
exclamation = form_data["is_exclamation"]
output = f"{greeting}, {name} {'!!!' if exclamation else ''}"
self.ok_dialog("Hello world result.", output, "Why, thank you!")
```
- If using forms, the Kubermagic
forms
module must be imported. - A form class is created with fields that will display to the user.
- The form is instantiated and displayed in Kubermagic with form_dialog().
- The callback method runs with the user input passed as the first argument when the user presses the default button.
The resulting form will display in the app when run.
Built-in Field classes
Common field attributes
label
The label argument lets you specify a "human-friendly" label for this field. The default label for a Field is generated from the field name by converting all underscores to spaces and upper-casing the first letter.
class TextField(label=None, initial="", placeholder="")
initial
The initial value
placeholder
Placeholder text if no text has been entered.
class DropdownField(label=None, choices=(), initial=None)
choices
A list or set of strings to use in the dropdown menu.
initial
The initial value
class CheckboxField(label=None, checked=False)
checked
If True (default False), the box will open with a checkmark.
Modifying forms after load
Forms can have their fields modified after load. For instance, one might want to load a list of tags from github for a dropdown field. This is done by creating a form field without the dynamic parameters. After the form is instantiated, one can populate those values by accessing the fields using form.fields
.
```python
class TestForm(forms.Form):
tag = forms.DropdownField()
...
form = TestForm()
form.fields["tag"].choices = ("Tag 1", "Tag 2", "Tag 3")
form.fields["tag"].initial = "Tag 2"
```
Convenience Libraries
The following libraries are included with Kubermagic and are ready to use out-of-the-box.
requests
A clean, user-friendly API for handling web requests. SOCKS support is included. Docs
urllib3
Python HTTP library with thread-safe connection pooling, file post support, sanity friendly, and more. Docs
pyyaml
PyYAML is a YAML parser and emitter for Python. Docs
Sharing actions
Actions can be written for personal user or shared to assist colleagues or clients. To share actions, it is recommended to create Action Packs
- a group of actions that is version controlled. These packs can be updated and shared throughout an organization.
The Config File
environment_variables
[list of strings] default: []
Additional environment variables that will be passed to the script. These need to be set by the user in Kubermagic's preferences. The script will warn the user in the console if there is a missing variable.
open_in_terminal
[bool] default: false
If true, action will open in a new terminal window instead of the Kubermagic console.
scope
[str]
must be one of "namespace", "pod", "container". Action will only be enabled if selection of scope has been made.
show_warning_text
[str]
On commands that might have irreversable effects on a system, this will display the specified warning message within an "OK/Cancel" dialog box.
use_name_matching_pattern
[str]
When scope
is set to pod
, will automatically select the first pod matching the glob-style pattern. This helps prevent the need to manually select a pod from a list. If multiple pods match the pattern, the first pod in alphabetical order will be used. If multiple pods match, but one of these pods is selected in teh table, the selected pod will be used. If a pod is selected that does not match pattern, the selection is ignored and the first matching pod is used.
Only basic * wildcards are currently supported.
- To match a pod containing "hello-minikube", use "*hello-minikube*".
- To match a pod starting with "hello-minikube", use "hello-minikube*"
is_smart_action
[bool] default: false
If true, and a main.py
file exists in the action, the action will be treated as a Smart Action.
Config Example
json
{
"open_in_terminal": false,
"scope": "namespace",
"environment_variables": ["GITHUB_TOKEN"],
"use_name_matching_pattern": "*scheduler*",
"is_smart_action": false
}
Icons
The action can be further dressed up by adding the following files to the action directory.
-
icon.png
- a 64x64 image that will display as the toolbar icon -
menu.png
- a 32x32 image that will display in the menubar
Examples
Shell Examples
Hello, World
```main.bash tab=
!/bin/bash
echo "Hello, World!"
```
Run a postgres query
Find a pod with the word postgrespod
in it, and return the currently running queries.
```main.bash tab=
!/bin/bash
echo "Fetching current processes"
$KUBECTL exec -it -n "$NAMESPACE" "$POD" -- psql host="$NAMESPACE-pgdb dbname=
```
config.json tab=
{
"use_name_matching_pattern": "*postgrespod*"
}
Open a shell
Open a new terminal window with the shell of a pod that contains apps
```main.bash tab=
!/bin/bash
$KUBECTL exec -it -n "$NAMESPACE" "$POD" -c containername sh
```
config.json tab=
{
"open_in_terminal": true,
"use_name_matching_pattern": "*apps*"
}
Port Forward and Open in Browser
Initiate port-forwarding from a pod and open a new browser window to that port.
To link two or more related actions together, one can run commands in the background and use wait
. (open_in_terminal
must be set for this action to run correctly as this will keep the port-forward process alive.)
```main.bash tab=
!/bin/env bash
$KUBECTL port-forward -n "$NAMESPACE" "$POD" 1443:443 &
P1=$!
sleep 2; open -a "Google Chrome" https://127.0.0.1:1443 &
P2=$!
wait $P1 $P2
```
Python Examples
Hello, World in Python
A simple Kubermagic python action.
```main.py tab=
from kubermagic import KubermagicAction
class Action(KubermagicAction):
def run(self):
print("Hello, world from python.")
```
A simple form
A python form class is created by inheriting from kubermagic.forms.Form
. Fields are declared as class properties. When the action is started, the run command is called and form displayed to the user. When the user completes the form, the data is passed back to the callback and a dialog is displayed to the user.
```main.py tab=
from kubermagic import KubermagicAction, forms
GREETING_CHOICES = (
'Hello',
'Goodbye',
)
class GreetingForm(forms.Form):
name = forms.TextField(placeholder="Your name")
greeting = forms.DropdownField(choices=GREETING_CHOICES)
is_exclamation = forms.CheckboxField(label="Add Exclamation", checked=False)
class Action(KubermagicAction):
def run(self):
form = GreetingForm()
self.form_dialog(
"Greeting Form", "Please select how you would like to be greeted.",
form, ok_button_text="Greet me", callback=self.greet_callback
)
def greet_callback(self, form_data):
print("Data from form:", form_data)
greeting = form_data["greeting"]
name = form_data["name"]
exclamation = form_data["is_exclamation"]
output = f"{greeting}, {name} {'!!!' if exclamation else ''}"
self.ok_dialog("Hello world result.", output, "Why, thank you!")
```