Introduce "scuemata" system for CUE-based specification of Grafana objects (#32527)
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
package load
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"path/filepath"
|
||||
|
||||
"cuelang.org/go/cue"
|
||||
"cuelang.org/go/cue/load"
|
||||
)
|
||||
|
||||
var rt = &cue.Runtime{}
|
||||
|
||||
// Families can have variants, where more typing information narrows the
|
||||
// possible values for certain keys in schemas. These are a meta-property
|
||||
// of the schema, effectively encoded in these loaders.
|
||||
//
|
||||
// We can generally define three variants:
|
||||
// - "Base": strictly core schema files, no plugins. (go:embed-able)
|
||||
// - "Dist": "Base" + plugins that ship with vanilla Grafana (go:embed-able)
|
||||
// - "Instance": "Dist" + the non-core plugins available in an actual, running Grafana
|
||||
|
||||
// BaseLoadPaths contains the configuration for loading a DistDashboard
|
||||
type BaseLoadPaths struct {
|
||||
// BaseCueFS should be rooted at a directory containing the filesystem layout
|
||||
// expected to exist at github.com/grafana/grafana/cue.
|
||||
BaseCueFS fs.FS
|
||||
|
||||
// DistPluginCueFS should point to some fs path (TBD) under which all core
|
||||
// plugins live.
|
||||
DistPluginCueFS fs.FS
|
||||
|
||||
// InstanceCueFS should point to a root dir in which non-core plugins live.
|
||||
// Normal case will be that this only happens when an actual Grafana
|
||||
// instance is making the call, and has a plugin dir to offer - though
|
||||
// external tools could always create their own dirs shaped like a Grafana
|
||||
// plugin dir, and point to those.
|
||||
InstanceCueFS fs.FS
|
||||
}
|
||||
|
||||
// toOverlay converts all .cue files in the fs.FS into Source entries in an
|
||||
// overlay map, as expected by load.Config.
|
||||
//
|
||||
// Each entry is placed in the map with the provided prefix - which must be an
|
||||
// absolute path - ahead of the actual path of the added file within the fs.FS.
|
||||
//
|
||||
// The function writes into the provided overlay map, to facilitate the
|
||||
// construction of a single overlay map from multiple fs.FS.
|
||||
//
|
||||
// All files reachable by walking the provided fs.FS are added to the overlay
|
||||
// map, on the premise that control over the FS is sufficient to allow any
|
||||
// desired filtering.
|
||||
func toOverlay(prefix string, vfs fs.FS, overlay map[string]load.Source) error {
|
||||
if !filepath.IsAbs(prefix) {
|
||||
return fmt.Errorf("must provide absolute path prefix when generating cue overlay, got %q", prefix)
|
||||
}
|
||||
|
||||
err := fs.WalkDir(vfs, ".", (func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if d.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
f, err := vfs.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b, err := io.ReadAll(f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
overlay[filepath.Join(prefix, path)] = load.FromBytes(b)
|
||||
return nil
|
||||
}))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user