Schemas: Replace registry generation and github workflow (#83490)
* Create small registries for core and composable kinds * Update workflow with new registries * Fix imports in plugin schemas and deleted old registry generation files * Remove verification and maturity * Modify registries and add missing composable information to make schemas in kind-registry work * Add missing aliases * Remove unused templates * Remove kinds verification * Format generated code * Add gen header * Delete unused code and clean path in composable template * Delete kind-registry loader * Delete unused code * Update License link * Update codeowners path * Sort imports * More cleanup * Remove verify-kinds.yml from codeowners * Fix lint * Update composable_kidns * Fix cue extension * Restore verify-kinds to avoid to push outdated kind's registry * Fix composable format * Restore code owners for verify-kinds * Remove verify check
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
"cuelang.org/go/cue"
|
||||
"github.com/grafana/codejen"
|
||||
"github.com/grafana/kindsys"
|
||||
"github.com/grafana/thema"
|
||||
@@ -59,3 +60,8 @@ type SchemaForGen struct {
|
||||
// Whether the schema is grouped. See https://github.com/grafana/thema/issues/62
|
||||
IsGroup bool
|
||||
}
|
||||
|
||||
type CueSchema struct {
|
||||
CueFile cue.Value
|
||||
FilePath string
|
||||
}
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/grafana/codejen"
|
||||
"github.com/grafana/kindsys"
|
||||
)
|
||||
|
||||
// BaseCoreRegistryJenny generates a static registry for core kinds that
|
||||
// only initializes their [kindsys.Kind]. No slot kinds are composed.
|
||||
//
|
||||
// Path should be the relative path to the directory that will contain the
|
||||
// generated registry. kindrelroot should be the repo-root-relative path to the
|
||||
// parent directory to all directories that contain generated kind bindings
|
||||
// (e.g. pkg/kind).
|
||||
func BaseCoreRegistryJenny(path, kindrelroot string) ManyToOne {
|
||||
return &genBaseRegistry{
|
||||
path: path,
|
||||
kindrelroot: kindrelroot,
|
||||
}
|
||||
}
|
||||
|
||||
type genBaseRegistry struct {
|
||||
path string
|
||||
kindrelroot string
|
||||
}
|
||||
|
||||
func (gen *genBaseRegistry) JennyName() string {
|
||||
return "BaseCoreRegistryJenny"
|
||||
}
|
||||
|
||||
func (gen *genBaseRegistry) Generate(kinds ...kindsys.Kind) (*codejen.File, error) {
|
||||
cores := make([]kindsys.Core, 0, len(kinds))
|
||||
for _, d := range kinds {
|
||||
if corekind, is := d.(kindsys.Core); is {
|
||||
cores = append(cores, corekind)
|
||||
}
|
||||
}
|
||||
if len(cores) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
if err := tmpls.Lookup("kind_registry.tmpl").Execute(buf, tvars_kind_registry{
|
||||
PackageName: filepath.Base(gen.path),
|
||||
KindPackagePrefix: filepath.ToSlash(filepath.Join("github.com/grafana/grafana", gen.kindrelroot)),
|
||||
Kinds: cores,
|
||||
}); err != nil {
|
||||
return nil, fmt.Errorf("failed executing kind registry template: %w", err)
|
||||
}
|
||||
|
||||
b, err := postprocessGoFile(genGoFile{
|
||||
path: gen.path,
|
||||
in: buf.Bytes(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return codejen.NewFile(filepath.Join(gen.path, "base_gen.go"), b, gen), nil
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"cuelang.org/go/cue"
|
||||
"github.com/grafana/codejen"
|
||||
)
|
||||
|
||||
var registryPath = filepath.Join("pkg", "registry", "schemas")
|
||||
|
||||
// CoreRegistryJenny generates a registry with all core kinds.
|
||||
type CoreRegistryJenny struct {
|
||||
}
|
||||
|
||||
func (jenny *CoreRegistryJenny) JennyName() string {
|
||||
return "CoreRegistryJenny"
|
||||
}
|
||||
|
||||
func (jenny *CoreRegistryJenny) Generate(cueFiles []CueSchema) (codejen.Files, error) {
|
||||
schemas := make([]Schema, len(cueFiles))
|
||||
for i, v := range cueFiles {
|
||||
name, err := getSchemaName(v.CueFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
schemas[i] = Schema{
|
||||
Name: name,
|
||||
FilePath: v.FilePath,
|
||||
}
|
||||
}
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
if err := tmpls.Lookup("core_registry.tmpl").Execute(buf, tvars_registry{
|
||||
Schemas: schemas,
|
||||
}); err != nil {
|
||||
return nil, fmt.Errorf("failed executing kind registry template: %w", err)
|
||||
}
|
||||
|
||||
b, err := format.Source(buf.Bytes())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
file := codejen.NewFile(filepath.Join(registryPath, "core_kind.go"), b, jenny)
|
||||
return codejen.Files{*file}, nil
|
||||
}
|
||||
|
||||
func getSchemaName(v cue.Value) (string, error) {
|
||||
name, err := getPackageName(v)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
name = strings.Replace(name, "-", "_", -1)
|
||||
return strings.ToLower(name), nil
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/grafana/codejen"
|
||||
"github.com/grafana/kindsys"
|
||||
)
|
||||
|
||||
// CoreKindJenny generates the implementation of [kindsys.Core] for the provided
|
||||
// kind declaration.
|
||||
//
|
||||
// gokindsdir should be the relative path to the parent directory that contains
|
||||
// all generated kinds.
|
||||
//
|
||||
// This generator only has output for core structured kinds.
|
||||
func CoreKindJenny(gokindsdir string, cfg *CoreKindJennyConfig) OneToOne {
|
||||
if cfg == nil {
|
||||
cfg = new(CoreKindJennyConfig)
|
||||
}
|
||||
if cfg.GenDirName == nil {
|
||||
cfg.GenDirName = func(def kindsys.Kind) string {
|
||||
return def.Props().Common().MachineName
|
||||
}
|
||||
}
|
||||
|
||||
return &coreKindJenny{
|
||||
gokindsdir: gokindsdir,
|
||||
cfg: cfg,
|
||||
}
|
||||
}
|
||||
|
||||
// CoreKindJennyConfig holds configuration options for [CoreKindJenny].
|
||||
type CoreKindJennyConfig struct {
|
||||
// GenDirName returns the name of the directory in which the file should be
|
||||
// generated. Defaults to DefForGen.Lineage().Name() if nil.
|
||||
GenDirName func(kindsys.Kind) string
|
||||
}
|
||||
|
||||
type coreKindJenny struct {
|
||||
gokindsdir string
|
||||
cfg *CoreKindJennyConfig
|
||||
}
|
||||
|
||||
var _ OneToOne = &coreKindJenny{}
|
||||
|
||||
func (gen *coreKindJenny) JennyName() string {
|
||||
return "CoreKindJenny"
|
||||
}
|
||||
|
||||
func (gen *coreKindJenny) Generate(kind kindsys.Kind) (*codejen.File, error) {
|
||||
if _, is := kind.(kindsys.Core); !is {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
path := filepath.Join(gen.gokindsdir, gen.cfg.GenDirName(kind), kind.Props().Common().MachineName+"_kind_gen.go")
|
||||
buf := new(bytes.Buffer)
|
||||
if err := tmpls.Lookup("kind_core.tmpl").Execute(buf, kind); err != nil {
|
||||
return nil, fmt.Errorf("failed executing kind_core template for %s: %w", path, err)
|
||||
}
|
||||
b, err := postprocessGoFile(genGoFile{
|
||||
path: path,
|
||||
in: buf.Bytes(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return codejen.NewFile(path, b, gen), nil
|
||||
}
|
||||
@@ -18,15 +18,15 @@ func (jenny *K8ResourcesJenny) JennyName() string {
|
||||
return "K8ResourcesJenny"
|
||||
}
|
||||
|
||||
func (jenny *K8ResourcesJenny) Generate(cueFiles []cue.Value) (codejen.Files, error) {
|
||||
func (jenny *K8ResourcesJenny) Generate(cueFiles []CueSchema) (codejen.Files, error) {
|
||||
files := make(codejen.Files, 0)
|
||||
for _, val := range cueFiles {
|
||||
pkg, err := getPackageName(val)
|
||||
pkg, err := getPackageName(val.CueFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resource, err := jenny.genResource(pkg, val)
|
||||
resource, err := jenny.genResource(pkg, val.CueFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+10
-6
@@ -7,7 +7,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/grafana/codejen"
|
||||
"github.com/grafana/kindsys"
|
||||
)
|
||||
|
||||
// All the parsed templates in the tmpl subdirectory
|
||||
@@ -33,11 +32,7 @@ type (
|
||||
From string
|
||||
Leader string
|
||||
}
|
||||
tvars_kind_registry struct {
|
||||
PackageName string
|
||||
KindPackagePrefix string
|
||||
Kinds []kindsys.Core
|
||||
}
|
||||
|
||||
tvars_resource struct {
|
||||
PackageName string
|
||||
KindName string
|
||||
@@ -51,4 +46,13 @@ type (
|
||||
tvars_status struct {
|
||||
PackageName string
|
||||
}
|
||||
|
||||
tvars_registry struct {
|
||||
Schemas []Schema
|
||||
}
|
||||
|
||||
Schema struct {
|
||||
Name string
|
||||
FilePath string
|
||||
}
|
||||
)
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
package schemas
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
||||
"cuelang.org/go/cue"
|
||||
"cuelang.org/go/cue/cuecontext"
|
||||
)
|
||||
|
||||
type CoreKind struct {
|
||||
Name string
|
||||
CueFile cue.Value
|
||||
}
|
||||
|
||||
func GetCoreKinds() ([]CoreKind, error) {
|
||||
ctx := cuecontext.New()
|
||||
kinds := make([]CoreKind, 0)
|
||||
|
||||
_, caller, _, _ := runtime.Caller(0)
|
||||
root := filepath.Join(caller, "../../../..")
|
||||
|
||||
{{- range .Schemas }}
|
||||
|
||||
{{ .Name }}Cue, err := loadCueFile(ctx, filepath.Join(root, "{{ .FilePath }}"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, CoreKind{
|
||||
Name: "{{ .Name }}",
|
||||
CueFile: {{ .Name }}Cue,
|
||||
})
|
||||
{{- end }}
|
||||
|
||||
return kinds, nil
|
||||
}
|
||||
|
||||
func loadCueFile(ctx *cue.Context, path string) (cue.Value, error) {
|
||||
cueFile, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return cue.Value{}, err
|
||||
}
|
||||
|
||||
return ctx.CompileBytes(cueFile), nil
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
package {{ .Props.MachineName }}
|
||||
|
||||
import (
|
||||
"github.com/grafana/kindsys"
|
||||
"github.com/grafana/thema"
|
||||
"github.com/grafana/thema/vmux"
|
||||
|
||||
"github.com/grafana/grafana/pkg/cuectx"
|
||||
)
|
||||
|
||||
// rootrel is the relative path from the grafana repository root to the
|
||||
// directory containing the .cue files in which this kind is defined. Necessary
|
||||
// for runtime errors related to the definition and/or lineage to provide
|
||||
// a real path to the correct .cue file.
|
||||
const rootrel string = "kinds/{{ .Props.MachineName }}"
|
||||
|
||||
// TODO standard generated docs
|
||||
type Kind struct {
|
||||
kindsys.Core
|
||||
lin thema.ConvergentLineage[*Resource]
|
||||
jcodec vmux.Codec
|
||||
valmux vmux.ValueMux[*Resource]
|
||||
}
|
||||
|
||||
// type guard - ensure generated Kind type satisfies the kindsys.Core interface
|
||||
var _ kindsys.Core = &Kind{}
|
||||
|
||||
// TODO standard generated docs
|
||||
func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) {
|
||||
def, err := cuectx.LoadCoreKindDef(rootrel, rt.Context(), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k := &Kind{}
|
||||
k.Core, err = kindsys.BindCore(rt, def, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Get the thema.Schema that the meta says is in the current version (which
|
||||
// codegen ensures is always the latest)
|
||||
cursch := thema.SchemaP(k.Core.Lineage(), def.Properties.CurrentVersion)
|
||||
tsch, err := thema.BindType(cursch, &Resource{})
|
||||
if err != nil {
|
||||
// Should be unreachable, modulo bugs in the Thema->Go code generator
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k.jcodec = vmux.NewJSONCodec("{{ .Props.MachineName }}.json")
|
||||
k.lin = tsch.ConvergentLineage()
|
||||
k.valmux = vmux.NewValueMux(k.lin.TypedSchema(), k.jcodec)
|
||||
return k, nil
|
||||
}
|
||||
|
||||
// ConvergentLineage returns the same [thema.Lineage] as Lineage, but bound (see [thema.BindType])
|
||||
// to the the {{ .Props.Name }} [Resource] type generated from the current schema, v{{ .Props.CurrentVersion }}.
|
||||
func (k *Kind) ConvergentLineage() thema.ConvergentLineage[*Resource] {
|
||||
return k.lin
|
||||
}
|
||||
|
||||
// JSONValueMux is a version multiplexer that maps a []byte containing JSON data
|
||||
// at any schematized dashboard version to an instance of {{ .Props.Name }} [Resource].
|
||||
//
|
||||
// Validation and translation errors emitted from this func will identify the
|
||||
// input bytes as "dashboard.json".
|
||||
//
|
||||
// This is a thin wrapper around Thema's [vmux.ValueMux].
|
||||
func (k *Kind) JSONValueMux(b []byte) (*Resource, thema.TranslationLacunas, error) {
|
||||
return k.valmux(b)
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package {{ .PackageName }}
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
{{range .Kinds }}
|
||||
"{{ $.KindPackagePrefix }}/{{ .Props.MachineName }}"{{end}}
|
||||
"github.com/grafana/grafana/pkg/cuectx"
|
||||
"github.com/grafana/kindsys"
|
||||
"github.com/grafana/thema"
|
||||
)
|
||||
|
||||
// Base is a registry of all Grafana core kinds. It is designed for use both inside
|
||||
// of Grafana itself, and for import by external Go programs wanting to work with Grafana's
|
||||
// kind system.
|
||||
//
|
||||
// The registry provides two modes for accessing core kinds:
|
||||
// * Per-kind methods, which return the kind-specific type, e.g. Dashboard() returns [dashboard.Dashboard].
|
||||
// * All(), which returns a slice of [kindsys.Core].
|
||||
//
|
||||
// Prefer the individual named methods for use cases where the particular kind(s) that
|
||||
// are needed are known to the caller. For example, a dashboard linter can know that it
|
||||
// specifically wants the dashboard kind.
|
||||
//
|
||||
// Prefer All() when performing operations generically across all kinds. For example,
|
||||
// a generic HTTP middleware for validating request bodies expected to contain some
|
||||
// kind-schematized type.
|
||||
type Base struct {
|
||||
all []kindsys.Core
|
||||
{{- range .Kinds }}
|
||||
{{ .Props.MachineName }} *{{ .Props.MachineName }}.Kind{{end}}
|
||||
}
|
||||
|
||||
// type guards
|
||||
var (
|
||||
{{- range .Kinds }}
|
||||
_ kindsys.Core = &{{ .Props.MachineName }}.Kind{}{{end}}
|
||||
)
|
||||
|
||||
{{range .Kinds }}
|
||||
// {{ .Props.Name }} returns the [kindsys.Interface] implementation for the {{ .Props.MachineName }} kind.
|
||||
func (b *Base) {{ .Props.Name }}() *{{ .Props.MachineName }}.Kind {
|
||||
return b.{{ .Props.MachineName }}
|
||||
}
|
||||
{{end}}
|
||||
|
||||
func doNewBase(rt *thema.Runtime) *Base {
|
||||
var err error
|
||||
reg := &Base{}
|
||||
|
||||
{{range .Kinds }}
|
||||
reg.{{ .Props.MachineName }}, err = {{ .Props.MachineName }}.NewKind(rt)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("error while initializing the {{ .Props.MachineName }} Kind: %s", err))
|
||||
}
|
||||
reg.all = append(reg.all, reg.{{ .Props.MachineName }})
|
||||
{{end}}
|
||||
|
||||
return reg
|
||||
}
|
||||
@@ -1,74 +1,14 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/dave/dst"
|
||||
"github.com/dave/dst/decorator"
|
||||
"github.com/dave/dst/dstutil"
|
||||
"golang.org/x/tools/imports"
|
||||
)
|
||||
|
||||
type genGoFile struct {
|
||||
path string
|
||||
walker dstutil.ApplyFunc
|
||||
in []byte
|
||||
}
|
||||
|
||||
func postprocessGoFile(cfg genGoFile) ([]byte, error) {
|
||||
fname := filepath.Base(cfg.path)
|
||||
buf := new(bytes.Buffer)
|
||||
fset := token.NewFileSet()
|
||||
gf, err := decorator.ParseFile(fset, fname, string(cfg.in), parser.ParseComments)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing generated file: %w", err)
|
||||
}
|
||||
|
||||
if cfg.walker != nil {
|
||||
dstutil.Apply(gf, cfg.walker, nil)
|
||||
|
||||
err = format.Node(buf, fset, gf)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error formatting Go AST: %w", err)
|
||||
}
|
||||
} else {
|
||||
buf = bytes.NewBuffer(cfg.in)
|
||||
}
|
||||
|
||||
byt, err := imports.Process(fname, buf.Bytes(), nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("goimports processing failed: %w", err)
|
||||
}
|
||||
|
||||
// Compare imports before and after; warn about performance if some were added
|
||||
gfa, _ := parser.ParseFile(fset, fname, string(byt), parser.ParseComments)
|
||||
imap := make(map[string]bool)
|
||||
for _, im := range gf.Imports {
|
||||
imap[im.Path.Value] = true
|
||||
}
|
||||
var added []string
|
||||
for _, im := range gfa.Imports {
|
||||
if !imap[im.Path.Value] {
|
||||
added = append(added, im.Path.Value)
|
||||
}
|
||||
}
|
||||
|
||||
if len(added) != 0 {
|
||||
// TODO improve the guidance in this error if/when we better abstract over imports to generate
|
||||
fmt.Fprintf(os.Stderr, "The following imports were added by goimports while generating %s: \n\t%s\nRelying on goimports to find imports significantly slows down code generation. Consider adding these to the relevant template.\n", cfg.path, strings.Join(added, "\n\t"))
|
||||
}
|
||||
|
||||
return byt, nil
|
||||
}
|
||||
|
||||
type prefixmod struct {
|
||||
prefix string
|
||||
replace string
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
//
|
||||
// Generated by:
|
||||
// kinds/gen.go
|
||||
// Using jennies:
|
||||
// CoreKindJenny
|
||||
//
|
||||
// Run 'make gen-cue' from repository root to regenerate.
|
||||
|
||||
package accesspolicy
|
||||
|
||||
import (
|
||||
"github.com/grafana/kindsys"
|
||||
"github.com/grafana/thema"
|
||||
"github.com/grafana/thema/vmux"
|
||||
|
||||
"github.com/grafana/grafana/pkg/cuectx"
|
||||
)
|
||||
|
||||
// rootrel is the relative path from the grafana repository root to the
|
||||
// directory containing the .cue files in which this kind is defined. Necessary
|
||||
// for runtime errors related to the definition and/or lineage to provide
|
||||
// a real path to the correct .cue file.
|
||||
const rootrel string = "kinds/accesspolicy"
|
||||
|
||||
// TODO standard generated docs
|
||||
type Kind struct {
|
||||
kindsys.Core
|
||||
lin thema.ConvergentLineage[*Resource]
|
||||
jcodec vmux.Codec
|
||||
valmux vmux.ValueMux[*Resource]
|
||||
}
|
||||
|
||||
// type guard - ensure generated Kind type satisfies the kindsys.Core interface
|
||||
var _ kindsys.Core = &Kind{}
|
||||
|
||||
// TODO standard generated docs
|
||||
func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) {
|
||||
def, err := cuectx.LoadCoreKindDef(rootrel, rt.Context(), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k := &Kind{}
|
||||
k.Core, err = kindsys.BindCore(rt, def, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Get the thema.Schema that the meta says is in the current version (which
|
||||
// codegen ensures is always the latest)
|
||||
cursch := thema.SchemaP(k.Core.Lineage(), def.Properties.CurrentVersion)
|
||||
tsch, err := thema.BindType(cursch, &Resource{})
|
||||
if err != nil {
|
||||
// Should be unreachable, modulo bugs in the Thema->Go code generator
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k.jcodec = vmux.NewJSONCodec("accesspolicy.json")
|
||||
k.lin = tsch.ConvergentLineage()
|
||||
k.valmux = vmux.NewValueMux(k.lin.TypedSchema(), k.jcodec)
|
||||
return k, nil
|
||||
}
|
||||
|
||||
// ConvergentLineage returns the same [thema.Lineage] as Lineage, but bound (see [thema.BindType])
|
||||
// to the the AccessPolicy [Resource] type generated from the current schema, v0.0.
|
||||
func (k *Kind) ConvergentLineage() thema.ConvergentLineage[*Resource] {
|
||||
return k.lin
|
||||
}
|
||||
|
||||
// JSONValueMux is a version multiplexer that maps a []byte containing JSON data
|
||||
// at any schematized dashboard version to an instance of AccessPolicy [Resource].
|
||||
//
|
||||
// Validation and translation errors emitted from this func will identify the
|
||||
// input bytes as "dashboard.json".
|
||||
//
|
||||
// This is a thin wrapper around Thema's [vmux.ValueMux].
|
||||
func (k *Kind) JSONValueMux(b []byte) (*Resource, thema.TranslationLacunas, error) {
|
||||
return k.valmux(b)
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
//
|
||||
// Generated by:
|
||||
// kinds/gen.go
|
||||
// Using jennies:
|
||||
// CoreKindJenny
|
||||
//
|
||||
// Run 'make gen-cue' from repository root to regenerate.
|
||||
|
||||
package dashboard
|
||||
|
||||
import (
|
||||
"github.com/grafana/kindsys"
|
||||
"github.com/grafana/thema"
|
||||
"github.com/grafana/thema/vmux"
|
||||
|
||||
"github.com/grafana/grafana/pkg/cuectx"
|
||||
)
|
||||
|
||||
// rootrel is the relative path from the grafana repository root to the
|
||||
// directory containing the .cue files in which this kind is defined. Necessary
|
||||
// for runtime errors related to the definition and/or lineage to provide
|
||||
// a real path to the correct .cue file.
|
||||
const rootrel string = "kinds/dashboard"
|
||||
|
||||
// TODO standard generated docs
|
||||
type Kind struct {
|
||||
kindsys.Core
|
||||
lin thema.ConvergentLineage[*Resource]
|
||||
jcodec vmux.Codec
|
||||
valmux vmux.ValueMux[*Resource]
|
||||
}
|
||||
|
||||
// type guard - ensure generated Kind type satisfies the kindsys.Core interface
|
||||
var _ kindsys.Core = &Kind{}
|
||||
|
||||
// TODO standard generated docs
|
||||
func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) {
|
||||
def, err := cuectx.LoadCoreKindDef(rootrel, rt.Context(), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k := &Kind{}
|
||||
k.Core, err = kindsys.BindCore(rt, def, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Get the thema.Schema that the meta says is in the current version (which
|
||||
// codegen ensures is always the latest)
|
||||
cursch := thema.SchemaP(k.Core.Lineage(), def.Properties.CurrentVersion)
|
||||
tsch, err := thema.BindType(cursch, &Resource{})
|
||||
if err != nil {
|
||||
// Should be unreachable, modulo bugs in the Thema->Go code generator
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k.jcodec = vmux.NewJSONCodec("dashboard.json")
|
||||
k.lin = tsch.ConvergentLineage()
|
||||
k.valmux = vmux.NewValueMux(k.lin.TypedSchema(), k.jcodec)
|
||||
return k, nil
|
||||
}
|
||||
|
||||
// ConvergentLineage returns the same [thema.Lineage] as Lineage, but bound (see [thema.BindType])
|
||||
// to the the Dashboard [Resource] type generated from the current schema, v0.0.
|
||||
func (k *Kind) ConvergentLineage() thema.ConvergentLineage[*Resource] {
|
||||
return k.lin
|
||||
}
|
||||
|
||||
// JSONValueMux is a version multiplexer that maps a []byte containing JSON data
|
||||
// at any schematized dashboard version to an instance of Dashboard [Resource].
|
||||
//
|
||||
// Validation and translation errors emitted from this func will identify the
|
||||
// input bytes as "dashboard.json".
|
||||
//
|
||||
// This is a thin wrapper around Thema's [vmux.ValueMux].
|
||||
func (k *Kind) JSONValueMux(b []byte) (*Resource, thema.TranslationLacunas, error) {
|
||||
return k.valmux(b)
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
//
|
||||
// Generated by:
|
||||
// kinds/gen.go
|
||||
// Using jennies:
|
||||
// CoreKindJenny
|
||||
//
|
||||
// Run 'make gen-cue' from repository root to regenerate.
|
||||
|
||||
package librarypanel
|
||||
|
||||
import (
|
||||
"github.com/grafana/kindsys"
|
||||
"github.com/grafana/thema"
|
||||
"github.com/grafana/thema/vmux"
|
||||
|
||||
"github.com/grafana/grafana/pkg/cuectx"
|
||||
)
|
||||
|
||||
// rootrel is the relative path from the grafana repository root to the
|
||||
// directory containing the .cue files in which this kind is defined. Necessary
|
||||
// for runtime errors related to the definition and/or lineage to provide
|
||||
// a real path to the correct .cue file.
|
||||
const rootrel string = "kinds/librarypanel"
|
||||
|
||||
// TODO standard generated docs
|
||||
type Kind struct {
|
||||
kindsys.Core
|
||||
lin thema.ConvergentLineage[*Resource]
|
||||
jcodec vmux.Codec
|
||||
valmux vmux.ValueMux[*Resource]
|
||||
}
|
||||
|
||||
// type guard - ensure generated Kind type satisfies the kindsys.Core interface
|
||||
var _ kindsys.Core = &Kind{}
|
||||
|
||||
// TODO standard generated docs
|
||||
func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) {
|
||||
def, err := cuectx.LoadCoreKindDef(rootrel, rt.Context(), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k := &Kind{}
|
||||
k.Core, err = kindsys.BindCore(rt, def, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Get the thema.Schema that the meta says is in the current version (which
|
||||
// codegen ensures is always the latest)
|
||||
cursch := thema.SchemaP(k.Core.Lineage(), def.Properties.CurrentVersion)
|
||||
tsch, err := thema.BindType(cursch, &Resource{})
|
||||
if err != nil {
|
||||
// Should be unreachable, modulo bugs in the Thema->Go code generator
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k.jcodec = vmux.NewJSONCodec("librarypanel.json")
|
||||
k.lin = tsch.ConvergentLineage()
|
||||
k.valmux = vmux.NewValueMux(k.lin.TypedSchema(), k.jcodec)
|
||||
return k, nil
|
||||
}
|
||||
|
||||
// ConvergentLineage returns the same [thema.Lineage] as Lineage, but bound (see [thema.BindType])
|
||||
// to the the LibraryPanel [Resource] type generated from the current schema, v0.0.
|
||||
func (k *Kind) ConvergentLineage() thema.ConvergentLineage[*Resource] {
|
||||
return k.lin
|
||||
}
|
||||
|
||||
// JSONValueMux is a version multiplexer that maps a []byte containing JSON data
|
||||
// at any schematized dashboard version to an instance of LibraryPanel [Resource].
|
||||
//
|
||||
// Validation and translation errors emitted from this func will identify the
|
||||
// input bytes as "dashboard.json".
|
||||
//
|
||||
// This is a thin wrapper around Thema's [vmux.ValueMux].
|
||||
func (k *Kind) JSONValueMux(b []byte) (*Resource, thema.TranslationLacunas, error) {
|
||||
return k.valmux(b)
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
//
|
||||
// Generated by:
|
||||
// kinds/gen.go
|
||||
// Using jennies:
|
||||
// CoreKindJenny
|
||||
//
|
||||
// Run 'make gen-cue' from repository root to regenerate.
|
||||
|
||||
package preferences
|
||||
|
||||
import (
|
||||
"github.com/grafana/kindsys"
|
||||
"github.com/grafana/thema"
|
||||
"github.com/grafana/thema/vmux"
|
||||
|
||||
"github.com/grafana/grafana/pkg/cuectx"
|
||||
)
|
||||
|
||||
// rootrel is the relative path from the grafana repository root to the
|
||||
// directory containing the .cue files in which this kind is defined. Necessary
|
||||
// for runtime errors related to the definition and/or lineage to provide
|
||||
// a real path to the correct .cue file.
|
||||
const rootrel string = "kinds/preferences"
|
||||
|
||||
// TODO standard generated docs
|
||||
type Kind struct {
|
||||
kindsys.Core
|
||||
lin thema.ConvergentLineage[*Resource]
|
||||
jcodec vmux.Codec
|
||||
valmux vmux.ValueMux[*Resource]
|
||||
}
|
||||
|
||||
// type guard - ensure generated Kind type satisfies the kindsys.Core interface
|
||||
var _ kindsys.Core = &Kind{}
|
||||
|
||||
// TODO standard generated docs
|
||||
func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) {
|
||||
def, err := cuectx.LoadCoreKindDef(rootrel, rt.Context(), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k := &Kind{}
|
||||
k.Core, err = kindsys.BindCore(rt, def, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Get the thema.Schema that the meta says is in the current version (which
|
||||
// codegen ensures is always the latest)
|
||||
cursch := thema.SchemaP(k.Core.Lineage(), def.Properties.CurrentVersion)
|
||||
tsch, err := thema.BindType(cursch, &Resource{})
|
||||
if err != nil {
|
||||
// Should be unreachable, modulo bugs in the Thema->Go code generator
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k.jcodec = vmux.NewJSONCodec("preferences.json")
|
||||
k.lin = tsch.ConvergentLineage()
|
||||
k.valmux = vmux.NewValueMux(k.lin.TypedSchema(), k.jcodec)
|
||||
return k, nil
|
||||
}
|
||||
|
||||
// ConvergentLineage returns the same [thema.Lineage] as Lineage, but bound (see [thema.BindType])
|
||||
// to the the Preferences [Resource] type generated from the current schema, v0.0.
|
||||
func (k *Kind) ConvergentLineage() thema.ConvergentLineage[*Resource] {
|
||||
return k.lin
|
||||
}
|
||||
|
||||
// JSONValueMux is a version multiplexer that maps a []byte containing JSON data
|
||||
// at any schematized dashboard version to an instance of Preferences [Resource].
|
||||
//
|
||||
// Validation and translation errors emitted from this func will identify the
|
||||
// input bytes as "dashboard.json".
|
||||
//
|
||||
// This is a thin wrapper around Thema's [vmux.ValueMux].
|
||||
func (k *Kind) JSONValueMux(b []byte) (*Resource, thema.TranslationLacunas, error) {
|
||||
return k.valmux(b)
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
//
|
||||
// Generated by:
|
||||
// kinds/gen.go
|
||||
// Using jennies:
|
||||
// CoreKindJenny
|
||||
//
|
||||
// Run 'make gen-cue' from repository root to regenerate.
|
||||
|
||||
package publicdashboard
|
||||
|
||||
import (
|
||||
"github.com/grafana/kindsys"
|
||||
"github.com/grafana/thema"
|
||||
"github.com/grafana/thema/vmux"
|
||||
|
||||
"github.com/grafana/grafana/pkg/cuectx"
|
||||
)
|
||||
|
||||
// rootrel is the relative path from the grafana repository root to the
|
||||
// directory containing the .cue files in which this kind is defined. Necessary
|
||||
// for runtime errors related to the definition and/or lineage to provide
|
||||
// a real path to the correct .cue file.
|
||||
const rootrel string = "kinds/publicdashboard"
|
||||
|
||||
// TODO standard generated docs
|
||||
type Kind struct {
|
||||
kindsys.Core
|
||||
lin thema.ConvergentLineage[*Resource]
|
||||
jcodec vmux.Codec
|
||||
valmux vmux.ValueMux[*Resource]
|
||||
}
|
||||
|
||||
// type guard - ensure generated Kind type satisfies the kindsys.Core interface
|
||||
var _ kindsys.Core = &Kind{}
|
||||
|
||||
// TODO standard generated docs
|
||||
func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) {
|
||||
def, err := cuectx.LoadCoreKindDef(rootrel, rt.Context(), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k := &Kind{}
|
||||
k.Core, err = kindsys.BindCore(rt, def, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Get the thema.Schema that the meta says is in the current version (which
|
||||
// codegen ensures is always the latest)
|
||||
cursch := thema.SchemaP(k.Core.Lineage(), def.Properties.CurrentVersion)
|
||||
tsch, err := thema.BindType(cursch, &Resource{})
|
||||
if err != nil {
|
||||
// Should be unreachable, modulo bugs in the Thema->Go code generator
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k.jcodec = vmux.NewJSONCodec("publicdashboard.json")
|
||||
k.lin = tsch.ConvergentLineage()
|
||||
k.valmux = vmux.NewValueMux(k.lin.TypedSchema(), k.jcodec)
|
||||
return k, nil
|
||||
}
|
||||
|
||||
// ConvergentLineage returns the same [thema.Lineage] as Lineage, but bound (see [thema.BindType])
|
||||
// to the the PublicDashboard [Resource] type generated from the current schema, v0.0.
|
||||
func (k *Kind) ConvergentLineage() thema.ConvergentLineage[*Resource] {
|
||||
return k.lin
|
||||
}
|
||||
|
||||
// JSONValueMux is a version multiplexer that maps a []byte containing JSON data
|
||||
// at any schematized dashboard version to an instance of PublicDashboard [Resource].
|
||||
//
|
||||
// Validation and translation errors emitted from this func will identify the
|
||||
// input bytes as "dashboard.json".
|
||||
//
|
||||
// This is a thin wrapper around Thema's [vmux.ValueMux].
|
||||
func (k *Kind) JSONValueMux(b []byte) (*Resource, thema.TranslationLacunas, error) {
|
||||
return k.valmux(b)
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
//
|
||||
// Generated by:
|
||||
// kinds/gen.go
|
||||
// Using jennies:
|
||||
// CoreKindJenny
|
||||
//
|
||||
// Run 'make gen-cue' from repository root to regenerate.
|
||||
|
||||
package role
|
||||
|
||||
import (
|
||||
"github.com/grafana/kindsys"
|
||||
"github.com/grafana/thema"
|
||||
"github.com/grafana/thema/vmux"
|
||||
|
||||
"github.com/grafana/grafana/pkg/cuectx"
|
||||
)
|
||||
|
||||
// rootrel is the relative path from the grafana repository root to the
|
||||
// directory containing the .cue files in which this kind is defined. Necessary
|
||||
// for runtime errors related to the definition and/or lineage to provide
|
||||
// a real path to the correct .cue file.
|
||||
const rootrel string = "kinds/role"
|
||||
|
||||
// TODO standard generated docs
|
||||
type Kind struct {
|
||||
kindsys.Core
|
||||
lin thema.ConvergentLineage[*Resource]
|
||||
jcodec vmux.Codec
|
||||
valmux vmux.ValueMux[*Resource]
|
||||
}
|
||||
|
||||
// type guard - ensure generated Kind type satisfies the kindsys.Core interface
|
||||
var _ kindsys.Core = &Kind{}
|
||||
|
||||
// TODO standard generated docs
|
||||
func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) {
|
||||
def, err := cuectx.LoadCoreKindDef(rootrel, rt.Context(), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k := &Kind{}
|
||||
k.Core, err = kindsys.BindCore(rt, def, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Get the thema.Schema that the meta says is in the current version (which
|
||||
// codegen ensures is always the latest)
|
||||
cursch := thema.SchemaP(k.Core.Lineage(), def.Properties.CurrentVersion)
|
||||
tsch, err := thema.BindType(cursch, &Resource{})
|
||||
if err != nil {
|
||||
// Should be unreachable, modulo bugs in the Thema->Go code generator
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k.jcodec = vmux.NewJSONCodec("role.json")
|
||||
k.lin = tsch.ConvergentLineage()
|
||||
k.valmux = vmux.NewValueMux(k.lin.TypedSchema(), k.jcodec)
|
||||
return k, nil
|
||||
}
|
||||
|
||||
// ConvergentLineage returns the same [thema.Lineage] as Lineage, but bound (see [thema.BindType])
|
||||
// to the the Role [Resource] type generated from the current schema, v0.0.
|
||||
func (k *Kind) ConvergentLineage() thema.ConvergentLineage[*Resource] {
|
||||
return k.lin
|
||||
}
|
||||
|
||||
// JSONValueMux is a version multiplexer that maps a []byte containing JSON data
|
||||
// at any schematized dashboard version to an instance of Role [Resource].
|
||||
//
|
||||
// Validation and translation errors emitted from this func will identify the
|
||||
// input bytes as "dashboard.json".
|
||||
//
|
||||
// This is a thin wrapper around Thema's [vmux.ValueMux].
|
||||
func (k *Kind) JSONValueMux(b []byte) (*Resource, thema.TranslationLacunas, error) {
|
||||
return k.valmux(b)
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
//
|
||||
// Generated by:
|
||||
// kinds/gen.go
|
||||
// Using jennies:
|
||||
// CoreKindJenny
|
||||
//
|
||||
// Run 'make gen-cue' from repository root to regenerate.
|
||||
|
||||
package rolebinding
|
||||
|
||||
import (
|
||||
"github.com/grafana/kindsys"
|
||||
"github.com/grafana/thema"
|
||||
"github.com/grafana/thema/vmux"
|
||||
|
||||
"github.com/grafana/grafana/pkg/cuectx"
|
||||
)
|
||||
|
||||
// rootrel is the relative path from the grafana repository root to the
|
||||
// directory containing the .cue files in which this kind is defined. Necessary
|
||||
// for runtime errors related to the definition and/or lineage to provide
|
||||
// a real path to the correct .cue file.
|
||||
const rootrel string = "kinds/rolebinding"
|
||||
|
||||
// TODO standard generated docs
|
||||
type Kind struct {
|
||||
kindsys.Core
|
||||
lin thema.ConvergentLineage[*Resource]
|
||||
jcodec vmux.Codec
|
||||
valmux vmux.ValueMux[*Resource]
|
||||
}
|
||||
|
||||
// type guard - ensure generated Kind type satisfies the kindsys.Core interface
|
||||
var _ kindsys.Core = &Kind{}
|
||||
|
||||
// TODO standard generated docs
|
||||
func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) {
|
||||
def, err := cuectx.LoadCoreKindDef(rootrel, rt.Context(), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k := &Kind{}
|
||||
k.Core, err = kindsys.BindCore(rt, def, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Get the thema.Schema that the meta says is in the current version (which
|
||||
// codegen ensures is always the latest)
|
||||
cursch := thema.SchemaP(k.Core.Lineage(), def.Properties.CurrentVersion)
|
||||
tsch, err := thema.BindType(cursch, &Resource{})
|
||||
if err != nil {
|
||||
// Should be unreachable, modulo bugs in the Thema->Go code generator
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k.jcodec = vmux.NewJSONCodec("rolebinding.json")
|
||||
k.lin = tsch.ConvergentLineage()
|
||||
k.valmux = vmux.NewValueMux(k.lin.TypedSchema(), k.jcodec)
|
||||
return k, nil
|
||||
}
|
||||
|
||||
// ConvergentLineage returns the same [thema.Lineage] as Lineage, but bound (see [thema.BindType])
|
||||
// to the the RoleBinding [Resource] type generated from the current schema, v0.0.
|
||||
func (k *Kind) ConvergentLineage() thema.ConvergentLineage[*Resource] {
|
||||
return k.lin
|
||||
}
|
||||
|
||||
// JSONValueMux is a version multiplexer that maps a []byte containing JSON data
|
||||
// at any schematized dashboard version to an instance of RoleBinding [Resource].
|
||||
//
|
||||
// Validation and translation errors emitted from this func will identify the
|
||||
// input bytes as "dashboard.json".
|
||||
//
|
||||
// This is a thin wrapper around Thema's [vmux.ValueMux].
|
||||
func (k *Kind) JSONValueMux(b []byte) (*Resource, thema.TranslationLacunas, error) {
|
||||
return k.valmux(b)
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
//
|
||||
// Generated by:
|
||||
// kinds/gen.go
|
||||
// Using jennies:
|
||||
// CoreKindJenny
|
||||
//
|
||||
// Run 'make gen-cue' from repository root to regenerate.
|
||||
|
||||
package team
|
||||
|
||||
import (
|
||||
"github.com/grafana/kindsys"
|
||||
"github.com/grafana/thema"
|
||||
"github.com/grafana/thema/vmux"
|
||||
|
||||
"github.com/grafana/grafana/pkg/cuectx"
|
||||
)
|
||||
|
||||
// rootrel is the relative path from the grafana repository root to the
|
||||
// directory containing the .cue files in which this kind is defined. Necessary
|
||||
// for runtime errors related to the definition and/or lineage to provide
|
||||
// a real path to the correct .cue file.
|
||||
const rootrel string = "kinds/team"
|
||||
|
||||
// TODO standard generated docs
|
||||
type Kind struct {
|
||||
kindsys.Core
|
||||
lin thema.ConvergentLineage[*Resource]
|
||||
jcodec vmux.Codec
|
||||
valmux vmux.ValueMux[*Resource]
|
||||
}
|
||||
|
||||
// type guard - ensure generated Kind type satisfies the kindsys.Core interface
|
||||
var _ kindsys.Core = &Kind{}
|
||||
|
||||
// TODO standard generated docs
|
||||
func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) {
|
||||
def, err := cuectx.LoadCoreKindDef(rootrel, rt.Context(), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k := &Kind{}
|
||||
k.Core, err = kindsys.BindCore(rt, def, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Get the thema.Schema that the meta says is in the current version (which
|
||||
// codegen ensures is always the latest)
|
||||
cursch := thema.SchemaP(k.Core.Lineage(), def.Properties.CurrentVersion)
|
||||
tsch, err := thema.BindType(cursch, &Resource{})
|
||||
if err != nil {
|
||||
// Should be unreachable, modulo bugs in the Thema->Go code generator
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k.jcodec = vmux.NewJSONCodec("team.json")
|
||||
k.lin = tsch.ConvergentLineage()
|
||||
k.valmux = vmux.NewValueMux(k.lin.TypedSchema(), k.jcodec)
|
||||
return k, nil
|
||||
}
|
||||
|
||||
// ConvergentLineage returns the same [thema.Lineage] as Lineage, but bound (see [thema.BindType])
|
||||
// to the the Team [Resource] type generated from the current schema, v0.0.
|
||||
func (k *Kind) ConvergentLineage() thema.ConvergentLineage[*Resource] {
|
||||
return k.lin
|
||||
}
|
||||
|
||||
// JSONValueMux is a version multiplexer that maps a []byte containing JSON data
|
||||
// at any schematized dashboard version to an instance of Team [Resource].
|
||||
//
|
||||
// Validation and translation errors emitted from this func will identify the
|
||||
// input bytes as "dashboard.json".
|
||||
//
|
||||
// This is a thin wrapper around Thema's [vmux.ValueMux].
|
||||
func (k *Kind) JSONValueMux(b []byte) (*Resource, thema.TranslationLacunas, error) {
|
||||
return k.valmux(b)
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/codejen"
|
||||
)
|
||||
|
||||
var registryPath = filepath.Join("pkg", "registry", "schemas")
|
||||
|
||||
var renamedPlugins = map[string]string{
|
||||
"cloud-monitoring": "googlecloudmonitoring",
|
||||
"grafana-pyroscope-datasource": "grafanapyroscope",
|
||||
"annolist": "annotationslist",
|
||||
"grafanatestdatadatasource": "testdata",
|
||||
"dashlist": "dashboardlist",
|
||||
}
|
||||
|
||||
type PluginRegistryJenny struct {
|
||||
}
|
||||
|
||||
func (jenny *PluginRegistryJenny) JennyName() string {
|
||||
return "PluginRegistryJenny"
|
||||
}
|
||||
|
||||
func (jenny *PluginRegistryJenny) Generate(files []string) (*codejen.File, error) {
|
||||
if len(files) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
schemas := make([]Schema, len(files))
|
||||
for i, file := range files {
|
||||
name, err := getSchemaName(file)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to find schema name: %s", err)
|
||||
}
|
||||
|
||||
schemas[i] = Schema{
|
||||
Name: name,
|
||||
Filename: filepath.Base(file),
|
||||
FilePath: file,
|
||||
}
|
||||
}
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
if err := tmpls.Lookup("composable_registry.tmpl").Execute(buf, tmpl_vars_plugin_registry{
|
||||
Schemas: schemas,
|
||||
}); err != nil {
|
||||
return nil, fmt.Errorf("failed executing kind registry template: %w", err)
|
||||
}
|
||||
|
||||
b, err := format.Source(buf.Bytes())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return codejen.NewFile(filepath.Join(registryPath, "composable_kind.go"), b, jenny), nil
|
||||
}
|
||||
|
||||
func getSchemaName(path string) (string, error) {
|
||||
parts := strings.Split(path, "/")
|
||||
if len(parts) < 2 {
|
||||
return "", fmt.Errorf("path should contain more than 2 elements")
|
||||
}
|
||||
folderName := parts[len(parts)-2]
|
||||
if renamed, ok := renamedPlugins[folderName]; ok {
|
||||
folderName = renamed
|
||||
}
|
||||
folderName = strings.ReplaceAll(folderName, "-", "")
|
||||
return strings.ToLower(folderName), nil
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/codejen"
|
||||
"github.com/grafana/grafana/pkg/plugins/pfs"
|
||||
)
|
||||
|
||||
const prefix = "github.com/grafana/grafana/public/app/plugins"
|
||||
|
||||
// PluginTreeListJenny creates a [codejen.ManyToOne] that produces Go code
|
||||
// for loading a [pfs.PluginList] given [*kindsys.PluginDecl] as inputs.
|
||||
func PluginTreeListJenny() codejen.ManyToOne[*pfs.PluginDecl] {
|
||||
outputFile := filepath.Join("pkg", "plugins", "pfs", "corelist", "corelist_load_gen.go")
|
||||
|
||||
return &ptlJenny{
|
||||
outputFile: outputFile,
|
||||
plugins: make(map[string]bool, 0),
|
||||
}
|
||||
}
|
||||
|
||||
type ptlJenny struct {
|
||||
outputFile string
|
||||
plugins map[string]bool
|
||||
}
|
||||
|
||||
func (j *ptlJenny) JennyName() string {
|
||||
return "PluginTreeListJenny"
|
||||
}
|
||||
|
||||
func (j *ptlJenny) Generate(decls ...*pfs.PluginDecl) (*codejen.File, error) {
|
||||
buf := new(bytes.Buffer)
|
||||
vars := templateVars_plugin_registry{
|
||||
Plugins: make([]struct {
|
||||
PkgName, Path, ImportPath string
|
||||
NoAlias bool
|
||||
}, 0, len(decls)),
|
||||
}
|
||||
|
||||
type tpl struct {
|
||||
PkgName, Path, ImportPath string
|
||||
NoAlias bool
|
||||
}
|
||||
|
||||
for _, decl := range decls {
|
||||
meta := decl.PluginMeta
|
||||
|
||||
if _, exists := j.plugins[meta.Id]; exists {
|
||||
continue
|
||||
}
|
||||
|
||||
pluginId := j.sanitizePluginId(meta.Id)
|
||||
vars.Plugins = append(vars.Plugins, tpl{
|
||||
PkgName: pluginId,
|
||||
NoAlias: pluginId != filepath.Base(decl.PluginPath),
|
||||
ImportPath: filepath.ToSlash(filepath.Join(prefix, decl.PluginPath)),
|
||||
Path: path.Join(append(strings.Split(prefix, "/")[3:], decl.PluginPath)...),
|
||||
})
|
||||
|
||||
j.plugins[meta.Id] = true
|
||||
}
|
||||
|
||||
if err := tmpls.Lookup("plugin_registry.tmpl").Execute(buf, vars); err != nil {
|
||||
return nil, fmt.Errorf("failed executing plugin registry template: %w", err)
|
||||
}
|
||||
|
||||
byt, err := postprocessGoFile(genGoFile{
|
||||
path: j.outputFile,
|
||||
in: buf.Bytes(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error postprocessing plugin registry: %w", err)
|
||||
}
|
||||
|
||||
return codejen.NewFile(j.outputFile, byt, j), nil
|
||||
}
|
||||
|
||||
func (j *ptlJenny) sanitizePluginId(s string) string {
|
||||
return strings.Map(func(r rune) rune {
|
||||
switch {
|
||||
case r >= 'a' && r <= 'z':
|
||||
fallthrough
|
||||
case r >= 'A' && r <= 'Z':
|
||||
fallthrough
|
||||
case r >= '0' && r <= '9':
|
||||
fallthrough
|
||||
case r == '_':
|
||||
return r
|
||||
case r == '-':
|
||||
return '_'
|
||||
default:
|
||||
return -1
|
||||
}
|
||||
}, s)
|
||||
}
|
||||
@@ -22,12 +22,13 @@ var tmplFS embed.FS
|
||||
// The following group of types, beginning with templateVars_*, all contain the set
|
||||
// of variables expected by the corresponding named template file under tmpl/
|
||||
type (
|
||||
templateVars_plugin_registry struct {
|
||||
Plugins []struct {
|
||||
PkgName string
|
||||
Path string
|
||||
ImportPath string
|
||||
NoAlias bool
|
||||
}
|
||||
tmpl_vars_plugin_registry struct {
|
||||
Schemas []Schema
|
||||
}
|
||||
|
||||
Schema struct {
|
||||
Name string
|
||||
Filename string
|
||||
FilePath string
|
||||
}
|
||||
)
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
package schemas
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing/fstest"
|
||||
|
||||
"cuelang.org/go/cue"
|
||||
"cuelang.org/go/cue/cuecontext"
|
||||
"cuelang.org/go/cue/load"
|
||||
)
|
||||
|
||||
var cueImportsPath = filepath.Join("packages", "grafana-schema", "src", "common")
|
||||
var importPath = "github.com/grafana/grafana/packages/grafana-schema/src/common"
|
||||
|
||||
type ComposableKind struct {
|
||||
Name string
|
||||
Filename string
|
||||
CueFile cue.Value
|
||||
}
|
||||
|
||||
func GetComposableKinds() ([]ComposableKind, error) {
|
||||
kinds := make([]ComposableKind, 0)
|
||||
|
||||
_, caller, _, _ := runtime.Caller(0)
|
||||
root := filepath.Join(caller, "../../../..")
|
||||
|
||||
{{- range .Schemas }}
|
||||
|
||||
{{ .Name }}Cue, err := loadCueFileWithCommon(root, filepath.Join(root, "{{ .FilePath }}"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "{{ .Name }}",
|
||||
Filename: "{{ .Filename }}",
|
||||
CueFile: {{ .Name }}Cue,
|
||||
})
|
||||
{{- end }}
|
||||
|
||||
return kinds, nil
|
||||
}
|
||||
|
||||
func loadCueFileWithCommon(root string, entrypoint string) (cue.Value, error) {
|
||||
commonFS, err := mockCommonFS(root)
|
||||
if err != nil {
|
||||
fmt.Printf("cannot load common cue files: %s\n", err)
|
||||
return cue.Value{}, err
|
||||
}
|
||||
|
||||
overlay, err := buildOverlay(commonFS)
|
||||
if err != nil {
|
||||
fmt.Printf("Cannot build overlay: %s\n", err)
|
||||
return cue.Value{}, err
|
||||
}
|
||||
|
||||
bis := load.Instances([]string{entrypoint}, &load.Config{
|
||||
ModuleRoot: "/",
|
||||
Overlay: overlay,
|
||||
})
|
||||
|
||||
values, err := cuecontext.New().BuildInstances(bis)
|
||||
if err != nil {
|
||||
fmt.Printf("Cannot build instance: %s\n", err)
|
||||
return cue.Value{}, err
|
||||
}
|
||||
|
||||
return values[0], nil
|
||||
}
|
||||
|
||||
func mockCommonFS(root string) (fs.FS, error) {
|
||||
path := filepath.Join(root, cueImportsPath)
|
||||
dir, err := os.ReadDir(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot open common cue files directory: %s", err)
|
||||
}
|
||||
|
||||
prefix := "cue.mod/pkg/" + importPath
|
||||
|
||||
commonFS := fstest.MapFS{}
|
||||
for _, d := range dir {
|
||||
if d.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
readPath := filepath.Join(path, d.Name())
|
||||
b, err := os.ReadFile(filepath.Clean(readPath))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
commonFS[filepath.Join(prefix, d.Name())] = &fstest.MapFile{Data: b}
|
||||
}
|
||||
|
||||
return commonFS, nil
|
||||
}
|
||||
|
||||
// It loads common cue files into the schema to be able to make import works
|
||||
func buildOverlay(commonFS fs.FS) (map[string]load.Source, error) {
|
||||
overlay := make(map[string]load.Source)
|
||||
|
||||
err := fs.WalkDir(commonFS, ".", func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if d.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
f, err := commonFS.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() { _ = f.Close() }()
|
||||
|
||||
b, err := io.ReadAll(f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
overlay[filepath.Join("/", path)] = load.FromBytes(b)
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return overlay, err
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package corelist
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"sync"
|
||||
"github.com/grafana/grafana"
|
||||
"github.com/grafana/grafana/pkg/plugins/pfs"
|
||||
"github.com/grafana/thema"
|
||||
)
|
||||
|
||||
func parsePluginOrPanic(path string, pkgname string, rt *thema.Runtime) pfs.ParsedPlugin {
|
||||
sub, err := fs.Sub(grafana.CueSchemaFS, path)
|
||||
if err != nil {
|
||||
panic("could not create fs sub to " + path)
|
||||
}
|
||||
pp, err := pfs.ParsePluginFS(sub, rt)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("error parsing plugin metadata for %s: %s", pkgname, err))
|
||||
}
|
||||
return pp
|
||||
}
|
||||
|
||||
func corePlugins(rt *thema.Runtime) []pfs.ParsedPlugin{
|
||||
return []pfs.ParsedPlugin{
|
||||
{{- range .Plugins }}
|
||||
parsePluginOrPanic("{{ .Path }}", "{{ .PkgName }}", rt),
|
||||
{{- end }}
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/dave/dst/decorator"
|
||||
"github.com/dave/dst/dstutil"
|
||||
"golang.org/x/tools/imports"
|
||||
)
|
||||
|
||||
type genGoFile struct {
|
||||
path string
|
||||
walker dstutil.ApplyFunc
|
||||
in []byte
|
||||
}
|
||||
|
||||
func postprocessGoFile(cfg genGoFile) ([]byte, error) {
|
||||
fname := filepath.Base(cfg.path)
|
||||
buf := new(bytes.Buffer)
|
||||
fset := token.NewFileSet()
|
||||
gf, err := decorator.ParseFile(fset, fname, string(cfg.in), parser.ParseComments)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing generated file: %w", err)
|
||||
}
|
||||
|
||||
if cfg.walker != nil {
|
||||
dstutil.Apply(gf, cfg.walker, nil)
|
||||
|
||||
err = format.Node(buf, fset, gf)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error formatting Go AST: %w", err)
|
||||
}
|
||||
} else {
|
||||
buf = bytes.NewBuffer(cfg.in)
|
||||
}
|
||||
|
||||
byt, err := imports.Process(fname, buf.Bytes(), nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("goimports processing failed: %w", err)
|
||||
}
|
||||
|
||||
// Compare imports before and after; warn about performance if some were added
|
||||
gfa, _ := parser.ParseFile(fset, fname, string(byt), parser.ParseComments)
|
||||
imap := make(map[string]bool)
|
||||
for _, im := range gf.Imports {
|
||||
imap[im.Path.Value] = true
|
||||
}
|
||||
var added []string
|
||||
for _, im := range gfa.Imports {
|
||||
if !imap[im.Path.Value] {
|
||||
added = append(added, im.Path.Value)
|
||||
}
|
||||
}
|
||||
|
||||
if len(added) != 0 {
|
||||
// TODO improve the guidance in this error if/when we better abstract over imports to generate
|
||||
fmt.Fprintf(os.Stderr, "The following imports were added by goimports while generating %s: \n\t%s\nRelying on goimports to find imports significantly slows down code generation. Consider adding these to the relevant template.\n", cfg.path, strings.Join(added, "\n\t"))
|
||||
}
|
||||
|
||||
return byt, nil
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package corekind
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/grafana/kindsys"
|
||||
"github.com/grafana/thema"
|
||||
|
||||
"github.com/grafana/grafana/pkg/cuectx"
|
||||
)
|
||||
|
||||
var (
|
||||
baseOnce sync.Once
|
||||
defaultBase *Base
|
||||
)
|
||||
|
||||
// NewBase provides a registry of all core raw and structured kinds, without any
|
||||
// composition of slot kinds.
|
||||
//
|
||||
// All calling code within grafana/grafana is expected to use Grafana's
|
||||
// singleton [thema.Runtime], returned from [cuectx.GrafanaThemaRuntime]. If nil
|
||||
// is passed, the singleton will be used.
|
||||
func NewBase(rt *thema.Runtime) *Base {
|
||||
allrt := cuectx.GrafanaThemaRuntime()
|
||||
if rt == nil || rt == allrt {
|
||||
baseOnce.Do(func() {
|
||||
defaultBase = doNewBase(allrt)
|
||||
})
|
||||
return defaultBase
|
||||
}
|
||||
|
||||
return doNewBase(rt)
|
||||
}
|
||||
|
||||
// All returns a slice of [kindsys.Core] containing all core Grafana kinds.
|
||||
//
|
||||
// The returned slice is sorted lexicographically by kind machine name.
|
||||
func (b *Base) All() []kindsys.Core {
|
||||
ret := make([]kindsys.Core, len(b.all))
|
||||
copy(ret, b.all)
|
||||
return ret
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
//
|
||||
// Generated by:
|
||||
// kinds/gen.go
|
||||
// Using jennies:
|
||||
// BaseCoreRegistryJenny
|
||||
//
|
||||
// Run 'make gen-cue' from repository root to regenerate.
|
||||
|
||||
package corekind
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/grafana/grafana/pkg/kinds/accesspolicy"
|
||||
"github.com/grafana/grafana/pkg/kinds/dashboard"
|
||||
"github.com/grafana/grafana/pkg/kinds/librarypanel"
|
||||
"github.com/grafana/grafana/pkg/kinds/preferences"
|
||||
"github.com/grafana/grafana/pkg/kinds/publicdashboard"
|
||||
"github.com/grafana/grafana/pkg/kinds/role"
|
||||
"github.com/grafana/grafana/pkg/kinds/rolebinding"
|
||||
"github.com/grafana/grafana/pkg/kinds/team"
|
||||
"github.com/grafana/kindsys"
|
||||
"github.com/grafana/thema"
|
||||
)
|
||||
|
||||
// Base is a registry of all Grafana core kinds. It is designed for use both inside
|
||||
// of Grafana itself, and for import by external Go programs wanting to work with Grafana's
|
||||
// kind system.
|
||||
//
|
||||
// The registry provides two modes for accessing core kinds:
|
||||
// - Per-kind methods, which return the kind-specific type, e.g. Dashboard() returns [dashboard.Dashboard].
|
||||
// - All(), which returns a slice of [kindsys.Core].
|
||||
//
|
||||
// Prefer the individual named methods for use cases where the particular kind(s) that
|
||||
// are needed are known to the caller. For example, a dashboard linter can know that it
|
||||
// specifically wants the dashboard kind.
|
||||
//
|
||||
// Prefer All() when performing operations generically across all kinds. For example,
|
||||
// a generic HTTP middleware for validating request bodies expected to contain some
|
||||
// kind-schematized type.
|
||||
type Base struct {
|
||||
all []kindsys.Core
|
||||
accesspolicy *accesspolicy.Kind
|
||||
dashboard *dashboard.Kind
|
||||
librarypanel *librarypanel.Kind
|
||||
preferences *preferences.Kind
|
||||
publicdashboard *publicdashboard.Kind
|
||||
role *role.Kind
|
||||
rolebinding *rolebinding.Kind
|
||||
team *team.Kind
|
||||
}
|
||||
|
||||
// type guards
|
||||
var (
|
||||
_ kindsys.Core = &accesspolicy.Kind{}
|
||||
_ kindsys.Core = &dashboard.Kind{}
|
||||
_ kindsys.Core = &librarypanel.Kind{}
|
||||
_ kindsys.Core = &preferences.Kind{}
|
||||
_ kindsys.Core = &publicdashboard.Kind{}
|
||||
_ kindsys.Core = &role.Kind{}
|
||||
_ kindsys.Core = &rolebinding.Kind{}
|
||||
_ kindsys.Core = &team.Kind{}
|
||||
)
|
||||
|
||||
// AccessPolicy returns the [kindsys.Interface] implementation for the accesspolicy kind.
|
||||
func (b *Base) AccessPolicy() *accesspolicy.Kind {
|
||||
return b.accesspolicy
|
||||
}
|
||||
|
||||
// Dashboard returns the [kindsys.Interface] implementation for the dashboard kind.
|
||||
func (b *Base) Dashboard() *dashboard.Kind {
|
||||
return b.dashboard
|
||||
}
|
||||
|
||||
// LibraryPanel returns the [kindsys.Interface] implementation for the librarypanel kind.
|
||||
func (b *Base) LibraryPanel() *librarypanel.Kind {
|
||||
return b.librarypanel
|
||||
}
|
||||
|
||||
// Preferences returns the [kindsys.Interface] implementation for the preferences kind.
|
||||
func (b *Base) Preferences() *preferences.Kind {
|
||||
return b.preferences
|
||||
}
|
||||
|
||||
// PublicDashboard returns the [kindsys.Interface] implementation for the publicdashboard kind.
|
||||
func (b *Base) PublicDashboard() *publicdashboard.Kind {
|
||||
return b.publicdashboard
|
||||
}
|
||||
|
||||
// Role returns the [kindsys.Interface] implementation for the role kind.
|
||||
func (b *Base) Role() *role.Kind {
|
||||
return b.role
|
||||
}
|
||||
|
||||
// RoleBinding returns the [kindsys.Interface] implementation for the rolebinding kind.
|
||||
func (b *Base) RoleBinding() *rolebinding.Kind {
|
||||
return b.rolebinding
|
||||
}
|
||||
|
||||
// Team returns the [kindsys.Interface] implementation for the team kind.
|
||||
func (b *Base) Team() *team.Kind {
|
||||
return b.team
|
||||
}
|
||||
|
||||
func doNewBase(rt *thema.Runtime) *Base {
|
||||
var err error
|
||||
reg := &Base{}
|
||||
|
||||
reg.accesspolicy, err = accesspolicy.NewKind(rt)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("error while initializing the accesspolicy Kind: %s", err))
|
||||
}
|
||||
reg.all = append(reg.all, reg.accesspolicy)
|
||||
|
||||
reg.dashboard, err = dashboard.NewKind(rt)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("error while initializing the dashboard Kind: %s", err))
|
||||
}
|
||||
reg.all = append(reg.all, reg.dashboard)
|
||||
|
||||
reg.librarypanel, err = librarypanel.NewKind(rt)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("error while initializing the librarypanel Kind: %s", err))
|
||||
}
|
||||
reg.all = append(reg.all, reg.librarypanel)
|
||||
|
||||
reg.preferences, err = preferences.NewKind(rt)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("error while initializing the preferences Kind: %s", err))
|
||||
}
|
||||
reg.all = append(reg.all, reg.preferences)
|
||||
|
||||
reg.publicdashboard, err = publicdashboard.NewKind(rt)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("error while initializing the publicdashboard Kind: %s", err))
|
||||
}
|
||||
reg.all = append(reg.all, reg.publicdashboard)
|
||||
|
||||
reg.role, err = role.NewKind(rt)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("error while initializing the role Kind: %s", err))
|
||||
}
|
||||
reg.all = append(reg.all, reg.role)
|
||||
|
||||
reg.rolebinding, err = rolebinding.NewKind(rt)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("error while initializing the rolebinding Kind: %s", err))
|
||||
}
|
||||
reg.all = append(reg.all, reg.rolebinding)
|
||||
|
||||
reg.team, err = team.NewKind(rt)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("error while initializing the team Kind: %s", err))
|
||||
}
|
||||
reg.all = append(reg.all, reg.team)
|
||||
|
||||
return reg
|
||||
}
|
||||
@@ -0,0 +1,468 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
//
|
||||
// Generated by:
|
||||
// public/app/plugins/gen.go
|
||||
// Using jennies:
|
||||
// PluginRegistryJenny
|
||||
//
|
||||
// Run 'make gen-cue' from repository root to regenerate.
|
||||
|
||||
package schemas
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing/fstest"
|
||||
|
||||
"cuelang.org/go/cue"
|
||||
"cuelang.org/go/cue/cuecontext"
|
||||
"cuelang.org/go/cue/load"
|
||||
)
|
||||
|
||||
var cueImportsPath = filepath.Join("packages", "grafana-schema", "src", "common")
|
||||
var importPath = "github.com/grafana/grafana/packages/grafana-schema/src/common"
|
||||
|
||||
type ComposableKind struct {
|
||||
Name string
|
||||
Filename string
|
||||
CueFile cue.Value
|
||||
}
|
||||
|
||||
func GetComposableKinds() ([]ComposableKind, error) {
|
||||
kinds := make([]ComposableKind, 0)
|
||||
|
||||
_, caller, _, _ := runtime.Caller(0)
|
||||
root := filepath.Join(caller, "../../../..")
|
||||
|
||||
azuremonitorCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/datasource/azuremonitor/dataquery.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "azuremonitor",
|
||||
Filename: "dataquery.cue",
|
||||
CueFile: azuremonitorCue,
|
||||
})
|
||||
|
||||
googlecloudmonitoringCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/datasource/cloud-monitoring/dataquery.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "googlecloudmonitoring",
|
||||
Filename: "dataquery.cue",
|
||||
CueFile: googlecloudmonitoringCue,
|
||||
})
|
||||
|
||||
cloudwatchCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/datasource/cloudwatch/dataquery.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "cloudwatch",
|
||||
Filename: "dataquery.cue",
|
||||
CueFile: cloudwatchCue,
|
||||
})
|
||||
|
||||
elasticsearchCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/datasource/elasticsearch/dataquery.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "elasticsearch",
|
||||
Filename: "dataquery.cue",
|
||||
CueFile: elasticsearchCue,
|
||||
})
|
||||
|
||||
grafanapyroscopeCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/datasource/grafana-pyroscope-datasource/dataquery.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "grafanapyroscope",
|
||||
Filename: "dataquery.cue",
|
||||
CueFile: grafanapyroscopeCue,
|
||||
})
|
||||
|
||||
grafanatestdatadatasourceCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/datasource/grafana-testdata-datasource/dataquery.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "grafanatestdatadatasource",
|
||||
Filename: "dataquery.cue",
|
||||
CueFile: grafanatestdatadatasourceCue,
|
||||
})
|
||||
|
||||
lokiCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/datasource/loki/dataquery.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "loki",
|
||||
Filename: "dataquery.cue",
|
||||
CueFile: lokiCue,
|
||||
})
|
||||
|
||||
parcaCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/datasource/parca/dataquery.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "parca",
|
||||
Filename: "dataquery.cue",
|
||||
CueFile: parcaCue,
|
||||
})
|
||||
|
||||
tempoCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/datasource/tempo/dataquery.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "tempo",
|
||||
Filename: "dataquery.cue",
|
||||
CueFile: tempoCue,
|
||||
})
|
||||
|
||||
alertgroupsCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/panel/alertGroups/panelcfg.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "alertgroups",
|
||||
Filename: "panelcfg.cue",
|
||||
CueFile: alertgroupsCue,
|
||||
})
|
||||
|
||||
annotationslistCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/panel/annolist/panelcfg.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "annotationslist",
|
||||
Filename: "panelcfg.cue",
|
||||
CueFile: annotationslistCue,
|
||||
})
|
||||
|
||||
barchartCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/panel/barchart/panelcfg.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "barchart",
|
||||
Filename: "panelcfg.cue",
|
||||
CueFile: barchartCue,
|
||||
})
|
||||
|
||||
bargaugeCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/panel/bargauge/panelcfg.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "bargauge",
|
||||
Filename: "panelcfg.cue",
|
||||
CueFile: bargaugeCue,
|
||||
})
|
||||
|
||||
candlestickCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/panel/candlestick/panelcfg.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "candlestick",
|
||||
Filename: "panelcfg.cue",
|
||||
CueFile: candlestickCue,
|
||||
})
|
||||
|
||||
canvasCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/panel/canvas/panelcfg.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "canvas",
|
||||
Filename: "panelcfg.cue",
|
||||
CueFile: canvasCue,
|
||||
})
|
||||
|
||||
dashboardlistCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/panel/dashlist/panelcfg.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "dashboardlist",
|
||||
Filename: "panelcfg.cue",
|
||||
CueFile: dashboardlistCue,
|
||||
})
|
||||
|
||||
datagridCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/panel/datagrid/panelcfg.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "datagrid",
|
||||
Filename: "panelcfg.cue",
|
||||
CueFile: datagridCue,
|
||||
})
|
||||
|
||||
debugCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/panel/debug/panelcfg.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "debug",
|
||||
Filename: "panelcfg.cue",
|
||||
CueFile: debugCue,
|
||||
})
|
||||
|
||||
gaugeCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/panel/gauge/panelcfg.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "gauge",
|
||||
Filename: "panelcfg.cue",
|
||||
CueFile: gaugeCue,
|
||||
})
|
||||
|
||||
geomapCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/panel/geomap/panelcfg.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "geomap",
|
||||
Filename: "panelcfg.cue",
|
||||
CueFile: geomapCue,
|
||||
})
|
||||
|
||||
heatmapCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/panel/heatmap/panelcfg.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "heatmap",
|
||||
Filename: "panelcfg.cue",
|
||||
CueFile: heatmapCue,
|
||||
})
|
||||
|
||||
histogramCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/panel/histogram/panelcfg.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "histogram",
|
||||
Filename: "panelcfg.cue",
|
||||
CueFile: histogramCue,
|
||||
})
|
||||
|
||||
logsCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/panel/logs/panelcfg.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "logs",
|
||||
Filename: "panelcfg.cue",
|
||||
CueFile: logsCue,
|
||||
})
|
||||
|
||||
newsCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/panel/news/panelcfg.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "news",
|
||||
Filename: "panelcfg.cue",
|
||||
CueFile: newsCue,
|
||||
})
|
||||
|
||||
nodegraphCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/panel/nodeGraph/panelcfg.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "nodegraph",
|
||||
Filename: "panelcfg.cue",
|
||||
CueFile: nodegraphCue,
|
||||
})
|
||||
|
||||
piechartCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/panel/piechart/panelcfg.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "piechart",
|
||||
Filename: "panelcfg.cue",
|
||||
CueFile: piechartCue,
|
||||
})
|
||||
|
||||
statCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/panel/stat/panelcfg.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "stat",
|
||||
Filename: "panelcfg.cue",
|
||||
CueFile: statCue,
|
||||
})
|
||||
|
||||
statetimelineCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/panel/state-timeline/panelcfg.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "statetimeline",
|
||||
Filename: "panelcfg.cue",
|
||||
CueFile: statetimelineCue,
|
||||
})
|
||||
|
||||
statushistoryCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/panel/status-history/panelcfg.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "statushistory",
|
||||
Filename: "panelcfg.cue",
|
||||
CueFile: statushistoryCue,
|
||||
})
|
||||
|
||||
tableCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/panel/table/panelcfg.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "table",
|
||||
Filename: "panelcfg.cue",
|
||||
CueFile: tableCue,
|
||||
})
|
||||
|
||||
textCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/panel/text/panelcfg.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "text",
|
||||
Filename: "panelcfg.cue",
|
||||
CueFile: textCue,
|
||||
})
|
||||
|
||||
timeseriesCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/panel/timeseries/panelcfg.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "timeseries",
|
||||
Filename: "panelcfg.cue",
|
||||
CueFile: timeseriesCue,
|
||||
})
|
||||
|
||||
trendCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/panel/trend/panelcfg.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "trend",
|
||||
Filename: "panelcfg.cue",
|
||||
CueFile: trendCue,
|
||||
})
|
||||
|
||||
xychartCue, err := loadCueFileWithCommon(root, filepath.Join(root, "./public/app/plugins/panel/xychart/panelcfg.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, ComposableKind{
|
||||
Name: "xychart",
|
||||
Filename: "panelcfg.cue",
|
||||
CueFile: xychartCue,
|
||||
})
|
||||
|
||||
return kinds, nil
|
||||
}
|
||||
|
||||
func loadCueFileWithCommon(root string, entrypoint string) (cue.Value, error) {
|
||||
commonFS, err := mockCommonFS(root)
|
||||
if err != nil {
|
||||
fmt.Printf("cannot load common cue files: %s\n", err)
|
||||
return cue.Value{}, err
|
||||
}
|
||||
|
||||
overlay, err := buildOverlay(commonFS)
|
||||
if err != nil {
|
||||
fmt.Printf("Cannot build overlay: %s\n", err)
|
||||
return cue.Value{}, err
|
||||
}
|
||||
|
||||
bis := load.Instances([]string{entrypoint}, &load.Config{
|
||||
ModuleRoot: "/",
|
||||
Overlay: overlay,
|
||||
})
|
||||
|
||||
values, err := cuecontext.New().BuildInstances(bis)
|
||||
if err != nil {
|
||||
fmt.Printf("Cannot build instance: %s\n", err)
|
||||
return cue.Value{}, err
|
||||
}
|
||||
|
||||
return values[0], nil
|
||||
}
|
||||
|
||||
func mockCommonFS(root string) (fs.FS, error) {
|
||||
path := filepath.Join(root, cueImportsPath)
|
||||
dir, err := os.ReadDir(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot open common cue files directory: %s", err)
|
||||
}
|
||||
|
||||
prefix := "cue.mod/pkg/" + importPath
|
||||
|
||||
commonFS := fstest.MapFS{}
|
||||
for _, d := range dir {
|
||||
if d.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
readPath := filepath.Join(path, d.Name())
|
||||
b, err := os.ReadFile(filepath.Clean(readPath))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
commonFS[filepath.Join(prefix, d.Name())] = &fstest.MapFile{Data: b}
|
||||
}
|
||||
|
||||
return commonFS, nil
|
||||
}
|
||||
|
||||
// It loads common cue files into the schema to be able to make import works
|
||||
func buildOverlay(commonFS fs.FS) (map[string]load.Source, error) {
|
||||
overlay := make(map[string]load.Source)
|
||||
|
||||
err := fs.WalkDir(commonFS, ".", func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if d.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
f, err := commonFS.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() { _ = f.Close() }()
|
||||
|
||||
b, err := io.ReadAll(f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
overlay[filepath.Join("/", path)] = load.FromBytes(b)
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return overlay, err
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
//
|
||||
// Generated by:
|
||||
// kinds/gen.go
|
||||
// Using jennies:
|
||||
// CoreRegistryJenny
|
||||
//
|
||||
// Run 'make gen-cue' from repository root to regenerate.
|
||||
|
||||
package schemas
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
||||
"cuelang.org/go/cue"
|
||||
"cuelang.org/go/cue/cuecontext"
|
||||
)
|
||||
|
||||
type CoreKind struct {
|
||||
Name string
|
||||
CueFile cue.Value
|
||||
}
|
||||
|
||||
func GetCoreKinds() ([]CoreKind, error) {
|
||||
ctx := cuecontext.New()
|
||||
kinds := make([]CoreKind, 0)
|
||||
|
||||
_, caller, _, _ := runtime.Caller(0)
|
||||
root := filepath.Join(caller, "../../../..")
|
||||
|
||||
accesspolicyCue, err := loadCueFile(ctx, filepath.Join(root, "./kinds/accesspolicy/access_policy_kind.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, CoreKind{
|
||||
Name: "accesspolicy",
|
||||
CueFile: accesspolicyCue,
|
||||
})
|
||||
|
||||
dashboardCue, err := loadCueFile(ctx, filepath.Join(root, "./kinds/dashboard/dashboard_kind.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, CoreKind{
|
||||
Name: "dashboard",
|
||||
CueFile: dashboardCue,
|
||||
})
|
||||
|
||||
librarypanelCue, err := loadCueFile(ctx, filepath.Join(root, "./kinds/librarypanel/librarypanel_kind.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, CoreKind{
|
||||
Name: "librarypanel",
|
||||
CueFile: librarypanelCue,
|
||||
})
|
||||
|
||||
preferencesCue, err := loadCueFile(ctx, filepath.Join(root, "./kinds/preferences/preferences_kind.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, CoreKind{
|
||||
Name: "preferences",
|
||||
CueFile: preferencesCue,
|
||||
})
|
||||
|
||||
publicdashboardCue, err := loadCueFile(ctx, filepath.Join(root, "./kinds/publicdashboard/public_dashboard_kind.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, CoreKind{
|
||||
Name: "publicdashboard",
|
||||
CueFile: publicdashboardCue,
|
||||
})
|
||||
|
||||
roleCue, err := loadCueFile(ctx, filepath.Join(root, "./kinds/role/role_kind.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, CoreKind{
|
||||
Name: "role",
|
||||
CueFile: roleCue,
|
||||
})
|
||||
|
||||
rolebindingCue, err := loadCueFile(ctx, filepath.Join(root, "./kinds/rolebinding/role_binding_kind.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, CoreKind{
|
||||
Name: "rolebinding",
|
||||
CueFile: rolebindingCue,
|
||||
})
|
||||
|
||||
teamCue, err := loadCueFile(ctx, filepath.Join(root, "./kinds/team/team_kind.cue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kinds = append(kinds, CoreKind{
|
||||
Name: "team",
|
||||
CueFile: teamCue,
|
||||
})
|
||||
|
||||
return kinds, nil
|
||||
}
|
||||
|
||||
func loadCueFile(ctx *cue.Context, path string) (cue.Value, error) {
|
||||
cueFile, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return cue.Value{}, err
|
||||
}
|
||||
|
||||
return ctx.CompileBytes(cueFile), nil
|
||||
}
|
||||
Reference in New Issue
Block a user