Database kind, step by step. Swap in your own kind’s group and fields as you go.
The example’s custom resource looks like this:Its operator labels each database’s pods with
platform.example.com/database: orders, and keeps its backups as DatabaseBackup objects labeled the same way.1
Find the kind and its fields
Open API resources in the sidebar and find your kind. Note its API group (
platform.example.com) and kind (Database). Then open an object of it, and look at its YAML tab: that’s where the paths you’ll use come from.2
Create the file
Plugins live in Create A plugin says what it is before what it shows: its own
~/.lumovi/plugins. Every .yaml or .yml file there is read, and each file is one plugin.~/.lumovi/plugins/databases.yaml with the smallest plugin there is, one view of one kind:databases.yaml
version, the oldest Lumovi it works with under needs, and the API groups its kinds are in. Every kind it names is in one of those groups. Its name is lowercase letters, digits and hyphens.In Lumovi, press ⌘R (Ctrl+R on Windows and Linux). API resources now shows databases.yaml under Shown by for the kind, and Lumovi uses the database icon for it. Everything in the next steps goes into that view, beside its kinds.3
Add columns
Columns come after the name and status, and replace the ones the API server prints.
type makes a column sort and read better: number right-aligns and sorts numerically, date reads like “2h ago” and sorts by time, boolean shows Yes or No, and count shows how many values a path finds.4
Say what healthy means
Status rules are checked in order, and the first that applies decides the status. If none applies, Lumovi falls back to the usual conventions.
health is one of healthy, progressing, warning, critical or neutral: it picks the color, the icon, the sort order and the filter chip. label is what the status says, and detail shows on hover. Both are templates: {{ .path }} puts a value in, and ?? gives a fallback when the path finds nothing.5
Add details
Details are facts shown in the detail panel’s Details section. They take the same fields as columns.
6
Link related objects
Links point to single objects, and appear under Related in the detail panel’s Overview: click one to open it. A link whose kind or name comes out empty isn’t shown.
kind is a built-in kind (Secret, Pod, Node…), or a kind and its group (Certificate.cert-manager.io). The namespace is this object’s unless you set one.7
List what belongs to it
Related lists are the objects of another kind that belong to this one, found by their labels or a field selector. Each is a tab in the detail panel, with the kind’s usual columns.
- A list of pods becomes the panel’s Pods tab, under its own name (Instances here), and brings Logs and Metrics tabs for those pods.
- Every list needs
labelsor afieldSelector, like'spec.nodeName={{ .status.nodeName }}'. - Lists look in this object’s namespace unless you set a
namespace. A list whose templates come out empty isn’t shown, since it would find the wrong objects.
8
Add actions
Actions patch the object, like
kubectl patch. They show up in the object’s ⋯ menu, its right-click menu and the command palette; primary: true also makes one a button in the detail panel.whenoffers an action only when it makes sense.undois a patch offered as Undo in the notification.confirmasks first, with this text. Without it (and without inputs, or an object to create), the action runs at once, and has to say so:runs: at-once.- A patch can’t change what’s the cluster’s to set, like an object’s owners, finalizers, name or namespace. See what a patch can’t change.
{{ now }}is the current time, as Kubernetes writes times: handy for annotations a controller watches.
9
Ask for a value
An action can ask for values before it runs: text, a number, or a choice. Its templates use them as Resize… opens a dialog with a New size field, starting at the current size. The
{{ input.name }}.undo is filled in from the database as it was before, so Undo puts the old size back. A number input (type: number) gives a number, and a choice (type: choice) is one of its options, or of the values a from path finds.10
Create objects
An action can create another object instead of patching this one, with Back up now… shows the backup as YAML before it’s created, with the name it will get, in the database’s namespace. Once it’s created, Open in the notification opens it. A value that’s a whole template copies what it finds, so
create in place of patch:spec: '{{ .spec }}' would copy the object’s whole spec. Creating can’t be undone from the notification.Every action checks your permissions first: it needs patch on the kind (or on its status, with subresource: status), or create on the kind it creates. It shows the equivalent command, kubectl patch or kubectl create, and can’t run in a read-only cluster.11
Give it a place in the sidebar
A place in the sidebar gathers your kinds under one entry, with everything of them in one list and a tab for each. Add a label and the kinds to the plugin’s See Plugins.
spec, beside views:12
Reload and check
Press ⌘R. If something’s wrong, All plugins, under Plugins in the sidebar, says so on the file’s row, Not in use. 1 problem to fix in the file., with the place in it:A plugin is used whole or not at all: with a problem anywhere in its file, none of it is used, and its kinds fall back to Lumovi’s own views or the API server’s columns until you fix it.
The whole plugin
databases.yaml
databases.yaml
databases.yaml
Good to know
- Quote templates and filters in YAML. A value that starts with
{{must be in quotes, or YAML reads it as a map. Quote paths with brackets or double quotes in them too, like'.status.conditions[?(@.type=="Ready")].status'. - A kind is one plugin’s. A plugin of yours shows kinds no other plugin has. To change how one of Lumovi’s plugins shows its kinds, copy its file from Lumovi’s plugins, keep its
metadata.name, and edit it: yours is used in its place, all of it. - Every kind of a group.
kind: '*'with agroupcovers every kind of that group, and the plugin then has that group to itself. A view for a kind itself wins over one for its group. See Whose a kind is. - A tool’s kinds, not Kubernetes’. Pods, Secrets and the other kinds Lumovi has pages for can’t be in a plugin. One it has no page for, like a Lease, a plugin can show without actions, named under
shows. - Another folder. Set
LUMOVI_PLUGINS_DIRto read plugins from somewhere else, like a folder your team shares in a Git repository. - Links work too. A link in the folder, named with
.yamlor.ymlat the end, is read like the file it points to, so you can link a plugin from elsewhere. A link to a file that’s gone can’t be read: All plugins lists it as not in use, with why, likeIt couldn’t be read: ENOENT: no such file or directory, …, and the other files still load. - Limits. Lumovi reads up to 200 files from the folder, each up to 256 KB. Its subfolders aren’t read, except a plugin with code, in the desktop app.
In your cluster: plugins everyone sees come from the chart’s
plugins value, one entry per file. People can’t add their own from the browser. See Plugins for everyone.Plugin format
Every field, path, condition and template, in one place.
Included plugins
Examples from cert-manager, Argo CD, Flux and more.