plugins: New static scanner and validator, with Thema slot support (#53754)

* coremodels: Convert plugin-metadata schema to a coremodel

* Newer cuetsy; try quoting field name

* Add slot definitions

* Start sketching out pfs package

* Rerun codegen with fixes, new cuetsy

* Catch up dashboard with new cuetsy

* Update to go1.18

* Use new vmuxers in thema

* Add slot system in Go

* Draft finished implementation of pfs

* Collapse slot pkg into coremodel dir; add PluginInfo

* Add the mux type on top of kernel

* Refactor plugin generator for extensibility

* Change models.cue package, numerous debugs

* Bring new output to parity with old

* Remove old plugin generation logic

* Misc tweaking

* Reintroduce generation of shared schemas

* Drop back to go1.17

* Add globbing to tsconfig exclude

* Introduce pfs test on existing testdata

* Make most existing testdata tests pass with pfs

* coremodels: Convert plugin-metadata schema to a coremodel

* Newer cuetsy; try quoting field name

* Add APIType control concept, regen pluginmeta

* Use proper numeric types for schema fields

* Make pluginmeta schema follow Go type breakdown

* More decomposition into distinct types

* Add test case for no plugin.json file

* Fix missing ref to #Dependencies

* Remove generated TS for pluginmeta

* Update dependencies, rearrange go.mod

* Regenerate without Model prefix

* Use updated thema loader; this is now runnable

* Skip app plugin with weird include

* Make plugin tree extractor reusable

* Split out slot lineage load/validate logic

* Add myriad tests for new plugin validation failures

* Add test for zip fixtures

* One last run of codegen

* Proper delinting

* Ensure validation order is deterministic

* Let there actually be sorting

* Undo reliance on builtIn field (#54009)

* undo builtIn reliance

* fix tests

Co-authored-by: Will Browne <wbrowne@users.noreply.github.com>
This commit is contained in:
sam boyer
2022-08-22 12:11:45 -04:00
committed by GitHub
co-authored by Will Browne
parent 828497447a
commit 4d433084a5
85 changed files with 1775 additions and 479 deletions
+18 -6
View File
@@ -1,6 +1,9 @@
package pluginmeta
import "github.com/grafana/thema"
import (
"github.com/grafana/thema"
"strings"
)
thema.#Lineage
name: "pluginmeta"
@@ -11,7 +14,8 @@ seqs: [
// Unique name of the plugin. If the plugin is published on
// grafana.com, then the plugin id has to follow the naming
// conventions.
id: =~"^[0-9a-z]+\\-([0-9a-z]+\\-)?(app|panel|datasource)$"
id: string & strings.MinRunes(1)
id: =~"^([0-9a-z]+\\-([0-9a-z]+\\-)?(app|panel|datasource))|(alertGroups|alertlist|annolist|barchart|bargauge|candlestick|canvas|dashlist|debug|gauge|geomap|gettingstarted|graph|heatmap|heatmap-old|histogram|icon|live|logs|news|nodeGraph|piechart|pluginlist|stat|state-timeline|status-history|table|table-old|text|timeseries|traces|welcome|xychart|alertmanager|cloudwatch|dashboard|elasticsearch|grafana|grafana-azure-monitor-datasource|graphite|influxdb|jaeger|loki|mixed|mssql|mysql|opentsdb|postgres|prometheus|stackdriver|tempo|testdata|zipkin)$"
// type indicates which type of Grafana plugin this is, of the defined
// set of Grafana plugin types.
@@ -41,6 +45,14 @@ seqs: [
// If the plugin has a backend component.
backend?: bool
// builtin indicates whether the plugin is developed and shipped as part
// of Grafana. Also known as a "core plugin."
builtIn: bool | *false
// hideFromList excludes the plugin from listings in Grafana's UI. Only
// allowed for builtin plugins.
hideFromList: bool | *false
// The first part of the file name of the backend component
// executable. There can be multiple executables built for
// different operating system and architecture. Grafana will
@@ -58,7 +70,7 @@ seqs: [
state?: #ReleaseState
// ReleaseState indicates release maturity state of a plugin.
#ReleaseState: "alpha" | "beta" | *"stable"
#ReleaseState: "alpha" | "beta" | "deprecated" | *"stable"
// Resources to include in plugin.
includes?: [...#Include]
@@ -185,7 +197,7 @@ seqs: [
}]
// SVG images that are used as plugin icons.
logos: {
logos?: {
// Link to the "small" version of the plugin logo, which must be
// an SVG image. "Large" and "small" logos can be the same image.
small: string
@@ -203,10 +215,10 @@ seqs: [
}]
// Date when this plugin was built.
updated: =~"^(\\d{4}-\\d{2}-\\d{2}|\\%TODAY\\%)$"
updated?: =~"^(\\d{4}-\\d{2}-\\d{2}|\\%TODAY\\%)$"
// Project version of this commit, e.g. `6.7.x`.
version: =~"^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*$|\\%VERSION\\%)"
version?: =~"^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*$|\\%VERSION\\%)"
}
#BuildInfo: {
+18 -8
View File
@@ -86,6 +86,8 @@ const (
ReleaseStateBeta ReleaseState = "beta"
ReleaseStateDeprecated ReleaseState = "deprecated"
ReleaseStateStable ReleaseState = "stable"
)
@@ -108,6 +110,10 @@ type Model struct {
// If the plugin has a backend component.
Backend *bool `json:"backend,omitempty"`
// builtin indicates whether the plugin is developed and shipped as part
// of Grafana. Also known as a "core plugin."
BuiltIn bool `json:"builtIn"`
// Plugin category used on the Add data source page.
Category *Category `json:"category,omitempty"`
@@ -146,6 +152,10 @@ type Model struct {
// request.
HiddenQueries *bool `json:"hiddenQueries,omitempty"`
// hideFromList excludes the plugin from listings in Grafana's UI. Only
// allowed for builtin plugins.
HideFromList bool `json:"hideFromList"`
// Unique name of the plugin. If the plugin is published on
// grafana.com, then the plugin id has to follow the naming
// conventions.
@@ -185,7 +195,7 @@ type Model struct {
} `json:"links,omitempty"`
// SVG images that are used as plugin icons.
Logos struct {
Logos *struct {
// Link to the "large" version of the plugin logo, which must be
// an SVG image. "Large" and "small" logos can be the same image.
Large string `json:"large"`
@@ -193,7 +203,7 @@ type Model struct {
// Link to the "small" version of the plugin logo, which must be
// an SVG image. "Large" and "small" logos can be the same image.
Small string `json:"small"`
} `json:"logos"`
} `json:"logos,omitempty"`
// An array of screenshot objects in the form `{name: 'bar', path:
// 'img/screenshot.png'}`
@@ -203,10 +213,10 @@ type Model struct {
} `json:"screenshots,omitempty"`
// Date when this plugin was built.
Updated string `json:"updated"`
Updated *string `json:"updated,omitempty"`
// Project version of this commit, e.g. `6.7.x`.
Version string `json:"version"`
Version *string `json:"version,omitempty"`
} `json:"info"`
// For data source plugins, if the plugin supports logs.
@@ -420,7 +430,7 @@ type Info struct {
} `json:"links,omitempty"`
// SVG images that are used as plugin icons.
Logos struct {
Logos *struct {
// Link to the "large" version of the plugin logo, which must be
// an SVG image. "Large" and "small" logos can be the same image.
Large string `json:"large"`
@@ -428,7 +438,7 @@ type Info struct {
// Link to the "small" version of the plugin logo, which must be
// an SVG image. "Large" and "small" logos can be the same image.
Small string `json:"small"`
} `json:"logos"`
} `json:"logos,omitempty"`
// An array of screenshot objects in the form `{name: 'bar', path:
// 'img/screenshot.png'}`
@@ -438,10 +448,10 @@ type Info struct {
} `json:"screenshots,omitempty"`
// Date when this plugin was built.
Updated string `json:"updated"`
Updated *string `json:"updated,omitempty"`
// Project version of this commit, e.g. `6.7.x`.
Version string `json:"version"`
Version *string `json:"version,omitempty"`
}
// TODO docs