mirror of
https://github.com/grafana/grafana.git
synced 2025-02-11 16:15:42 -06:00
4db3b2fd5c
* kindsys: Remove defs, Slot->SchemaInterface * Remove excess file * Fix up tests * Regenerate kinds report * Final bits of cleanup * Stop complaining, linter * Update pkg/kindsys/kindcat_composable.cue Co-authored-by: Tania <yalyna.ts@gmail.com> Co-authored-by: Tania <yalyna.ts@gmail.com>
122 lines
3.3 KiB
Go
122 lines
3.3 KiB
Go
package kindsys
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
|
|
"cuelang.org/go/cue"
|
|
"github.com/grafana/grafana/pkg/cuectx"
|
|
)
|
|
|
|
// SchemaInterface represents one of Grafana's named schema interfaces.
|
|
//
|
|
// Canonical definition of schema interfaces is done in CUE. Instances of
|
|
// this type simply represent that information in Go.
|
|
// TODO link to framework docs
|
|
type SchemaInterface struct {
|
|
name string
|
|
group bool
|
|
raw cue.Value
|
|
plugins []string
|
|
}
|
|
|
|
// Name returns the name of the SchemaInterface.
|
|
//
|
|
// The name is also used as the path at which a SchemaInterface lineage is defined in a
|
|
// plugin models.cue file.
|
|
func (s SchemaInterface) Name() string {
|
|
return s.name
|
|
}
|
|
|
|
// Interface returns the cue.Value representing the meta-schema that is the
|
|
// contract between core or custom kinds that compose the meta-schema, and the
|
|
// plugin-declared composable kinds that implement the meta-schema.
|
|
func (s SchemaInterface) Interface() cue.Value {
|
|
return s.raw.LookupPath(ip)
|
|
}
|
|
|
|
var ip = cue.ParsePath("interface")
|
|
|
|
// Should indicates whether the given plugin type is expected (but not required)
|
|
// to produce a composable kind that implements this SchemaInterface.
|
|
func (s SchemaInterface) Should(plugintype string) bool {
|
|
pt := plugintype
|
|
for _, t := range s.plugins {
|
|
if pt == t {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// IsGroup indicates whether the slot specifies a group lineage - one in which
|
|
// each top-level key represents a distinct schema for objects that are expected
|
|
// to exist in the wild, but objects corresponding to the root of the schema are not
|
|
// expected to exist.
|
|
func (s SchemaInterface) IsGroup() bool {
|
|
return s.group
|
|
}
|
|
|
|
func FindSchemaInterface(name string) (SchemaInterface, error) {
|
|
sl, has := SchemaInterfaces(nil)[name]
|
|
if !has {
|
|
return SchemaInterface{}, fmt.Errorf("unsupported slot: %s", name)
|
|
}
|
|
return sl, nil
|
|
}
|
|
|
|
var defaultIfaces map[string]SchemaInterface
|
|
var onceIfaces sync.Once
|
|
|
|
// SchemaInterfaces returns a map of all [SchemaInterface]s defined by
|
|
// Grafana's kindsys framework.
|
|
//
|
|
// All calling code within grafana/grafana is expected to use Grafana's
|
|
// singleton [cue.Context], returned from [cuectx.GrafanaCUEContext]. If nil is
|
|
// passed, the singleton will be used. This is a reasonable default for external
|
|
// code, as well.
|
|
//
|
|
// TODO link to framework docs
|
|
func SchemaInterfaces(ctx *cue.Context) map[string]SchemaInterface {
|
|
if ctx == nil || ctx == cuectx.GrafanaCUEContext() {
|
|
// Ensure framework is loaded, even if this func is called
|
|
// from an init() somewhere.
|
|
onceIfaces.Do(func() {
|
|
defaultIfaces = doSchemaInterfaces(nil)
|
|
})
|
|
return defaultIfaces
|
|
}
|
|
|
|
return doSchemaInterfaces(ctx)
|
|
}
|
|
|
|
func doSchemaInterfaces(ctx *cue.Context) map[string]SchemaInterface {
|
|
fw := CUEFramework(ctx)
|
|
|
|
defs := fw.LookupPath(cue.ParsePath("schemaInterfaces"))
|
|
if !defs.Exists() {
|
|
panic("schemaInterfaces key does not exist in kindsys framework")
|
|
}
|
|
type typ struct {
|
|
Name string `json:"name"`
|
|
PluginTypes []string `json:"pluginTypes"`
|
|
Group bool `json:"group"`
|
|
}
|
|
|
|
ifaces := make(map[string]SchemaInterface)
|
|
iter, _ := defs.Fields() //nolint:errcheck
|
|
for iter.Next() {
|
|
k := iter.Selector().String()
|
|
v := &typ{}
|
|
_ = iter.Value().Decode(&v) //nolint:errcheck,gosec
|
|
ifaces[k] = SchemaInterface{
|
|
name: v.Name,
|
|
plugins: v.PluginTypes,
|
|
group: v.Group,
|
|
raw: iter.Value(),
|
|
}
|
|
}
|
|
|
|
return ifaces
|
|
}
|