uiPanels
Configure SQL-backed tabs for Lunar dashboard extension points through the uiPanels section of lunar-config.yml.
lunar-config.yml -> uiPanelsType:
objectOptional
Form:
uiPanels: <extension-point-id>: <panel-file-path> <extension-point-id>: <panel-file-path> ...
UI panels add SQL-backed content to Lunar dashboard extension points. Lunar currently provides three: the Release Notes, Compliance and Artifacts tabs in the Release Ledger dashboard. Use them to display data recorded by your collectors or other data available to the bundled dashboards.
Each uiPanels entry maps a supported extension-point ID to a YAML panel file in the configuration repository. The file declares one or more tabs. Each tab runs a read-only query through Grafana's database connection and renders the result as a table or Markdown.
Lunar validates and stores the panel file with the manifest. Publishing or rolling back the configuration updates the panel at the same time.
Example uiPanels definition:
uiPanels:
release-notes: uipanels/release-notes.yml
release-evidence: uipanels/release-evidence.yml
release-artifacts: uipanels/release-artifacts.ymlExtension point
lunar-config.yml -> uiPanels.<extension-point-id>Type:
stringForm:
<extension-point-id>: <panel-file-path>
The key is the ID of an extension point, and the value is the path of its panel file relative to the configuration repository root. The supported IDs are as follows:
release-notes
The Release Notes tab of the Release Ledger dashboard.
:component, :sha
release-evidence
The Compliance tab of the Release Ledger dashboard.
:component, :sha
release-artifacts
The Artifacts tab of the Release Ledger dashboard.
:component, :sha
The dashboard passes the listed parameters to every tab's SQL. Extension-point IDs are validated by the Hub version handling the pull. Upgrade the Hub before adding an ID introduced by a newer release: an unsupported ID fails the entire configuration pull, including pulls of configuration-repository branches in CI, so it cannot be staged on a branch ahead of the Hub upgrade. Until the configuration defines a panel, the tab shows a note naming the key to add.
A release-notes panel describes what shipped in the release at :sha. How far back that reaches is the panel's decision. The example panel in hub/uipanel/examples/ reads the deployment attempts each release records under .deployment.attempts, takes the newest release before :sha with an approved attempt as the previous deployment, and lists the pull requests and tickets of every release after it, up to and including :sha. When no earlier release was deployed, it lists everything up to :sha.
Panel file
Type: YAML file
Form:
A panel file declares the tabs of one extension point. It must declare at least one, and a file with a single tab renders its content without a tab bar. The file may not exceed 64 KiB because Lunar stores it with the manifest and sends it to the browser on every panel view.
This minimal release-evidence panel shows the release commit and collection time in a table, then renders a note for the same commit as Markdown:
For complete replacements for the former built-in tabs, copy the ready-made panel files from hub/uipanel/examples/. Adjust them to match the collectors you run.
Tab
<panel-file> -> tabs.<tab-index>Type:
objectForms:
Table form:
Markdown form:
Each tab defines one query and how Lunar renders its result. Tabs fail independently at view time: one tab can show an error while the others render.
name
<panel-file> -> tabs.<tab-index>.nameType:
stringRequired
The tab's title. Names must be unique within the file.
type
<panel-file> -> tabs.<tab-index>.typeType:
stringValues:
table,markdownRequired
Controls how Lunar renders the query result. A table tab displays each returned row with the columns listed in columns. A markdown tab renders the sqlId column from the first row as Markdown.
sql
<panel-file> -> tabs.<tab-index>.sqlType:
stringRequired
The read-only SQL query. Unqualified table names resolve in public, where Lunar exposes the documented SQL API views. Qualify names in other schemas.
Refer to extension-point parameters as :name. Lunar substitutes each parameter as a quoted SQL string literal, so its value remains data. A ::type cast is not a parameter.
A query that names an unsupported parameter fails the pull. Lunar warns when no tab uses an available parameter, since omitting :component shows the same rows for every component.
Lunar does not execute SQL during configuration validation. Syntax errors and unknown table names appear on the dashboard when the tab loads.
columns
<panel-file> -> tabs.<tab-index>.columnsType:
arrayRequired in Table form
The columns to show, in order, each naming a query output column. Output columns not listed are not displayed but can be used in link templates. See Column.
sqlId
<panel-file> -> tabs.<tab-index>.sqlIdType:
stringRequired in Markdown form
The query output column holding the Markdown. Lunar renders headings, paragraphs, bullet lists, bold, italics, code, and links. It displays raw HTML as text. Links follow the same URL rules as a column's link. No rows means an empty tab.
Column
<panel-file> -> tabs.<tab-index>.columns.<column-index>Type:
objectForm:
sqlId
<panel-file> -> tabs.<tab-index>.columns.<column-index>.sqlIdType:
stringRequired
The query output column to show. It must be unique within the tab. A column the query does not return is reported on the tab.
name
<panel-file> -> tabs.<tab-index>.columns.<column-index>.nameType:
stringOptional
The header text. Defaults to sqlId.
width
<panel-file> -> tabs.<tab-index>.columns.<column-index>.widthType:
integerOptional
The column width in pixels, applied exactly. Values that do not fit are cut with an ellipsis and shown in full on hover. Columns without a width share the remaining space and wrap, so leave the free-text column unsized.
alignment
<panel-file> -> tabs.<tab-index>.columns.<column-index>.alignmentType:
stringValues:
left,center,rightOptional
The text alignment of the column.
color
<panel-file> -> tabs.<tab-index>.columns.<column-index>.colorType:
stringOptional
A CSS color for the cell text: a #hex value, a color keyword, or an rgb() / hsl() function.
link
<panel-file> -> tabs.<tab-index>.columns.<column-index>.linkType:
stringOptional
A URL template that turns each cell into a link. Inside a larger template, ${col} is replaced per row with that query column's percent-encoded value:
When the whole template is exactly ${col}, that column supplies the complete URL. This can link one displayed column using a URL returned in another, undisplayed query column:
The URL must start with http://, https://, or / for a path on the Grafana host (/d/<uid>/... links to another dashboard). Lunar rejects other schemes and protocol-relative //host URLs at render time; it also validates every link whose scheme is present in the template at pull time.
What a tab can read
Tabs use Grafana's database connection and inherit the bundled dashboards' read access. This includes:
the documented SQL API views in
public, includingpublic.componentsandpublic.checks;views and helper functions in the
grafanaschema;the internal Hub schemas used by the bundled dashboards.
Lunar runs tab queries read-only.
Validation
Use lunar hub pull --dry-run to run the same panel-file checks without publishing the configuration. A validation error stops the pull, and the last published configuration stays active.
Query limits
A table tab returns at most 200 rows and indicates when the result is truncated. This limit controls what reaches the browser, not the database work. Add an ORDER BY clause when row order matters.
A query that omits its :component filter can scan a whole table whenever someone views the panel. Self-hosted operators can limit query duration; see Limit Grafana query time.
Last updated
