Schema: Add basic folder schema (#67561)

This commit is contained in:
Ryan McKinley 2023-05-03 13:07:39 -07:00 committed by GitHub
parent 5765514397
commit 881ed3b599
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 381 additions and 4 deletions

View File

@ -0,0 +1,103 @@
---
keywords:
- grafana
- schema
title: Folder kind
---
> Both documentation generation and kinds schemas are in active development and subject to change without prior notice.
## Folder
#### Maturity: [merged](../../../maturity/#merged)
#### Version: 0.0
A folder is a collection of resources that are grouped together and can share permissions.
| Property | Type | Required | Default | Description |
|------------|---------------------|----------|---------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `metadata` | [object](#metadata) | **Yes** | | metadata contains embedded CommonMetadata and can be extended with custom string fields<br/>TODO: use CommonMetadata instead of redefining here; currently needs to be defined here<br/>without external reference as using the CommonMetadata reference breaks thema codegen. |
| `spec` | [object](#spec) | **Yes** | | |
| `status` | [object](#status) | **Yes** | | |
### Metadata
metadata contains embedded CommonMetadata and can be extended with custom string fields
TODO: use CommonMetadata instead of redefining here; currently needs to be defined here
without external reference as using the CommonMetadata reference breaks thema codegen.
It extends [_kubeObjectMetadata](#_kubeobjectmetadata).
| Property | Type | Required | Default | Description |
|---------------------|------------------------|----------|---------|-----------------------------------------------------------------------------------------------------------------------------------------|
| `createdBy` | string | **Yes** | | |
| `creationTimestamp` | string | **Yes** | | *(Inherited from [_kubeObjectMetadata](#_kubeobjectmetadata))* |
| `extraFields` | [object](#extrafields) | **Yes** | | extraFields is reserved for any fields that are pulled from the API server metadata but do not have concrete fields in the CUE metadata |
| `finalizers` | string[] | **Yes** | | *(Inherited from [_kubeObjectMetadata](#_kubeobjectmetadata))* |
| `labels` | map[string]string | **Yes** | | *(Inherited from [_kubeObjectMetadata](#_kubeobjectmetadata))* |
| `resourceVersion` | string | **Yes** | | *(Inherited from [_kubeObjectMetadata](#_kubeobjectmetadata))* |
| `uid` | string | **Yes** | | *(Inherited from [_kubeObjectMetadata](#_kubeobjectmetadata))* |
| `updateTimestamp` | string | **Yes** | | |
| `updatedBy` | string | **Yes** | | |
| `deletionTimestamp` | string | No | | *(Inherited from [_kubeObjectMetadata](#_kubeobjectmetadata))* |
### _kubeObjectMetadata
_kubeObjectMetadata is metadata found in a kubernetes object's metadata field.
It is not exhaustive and only includes fields which may be relevant to a kind's implementation,
As it is also intended to be generic enough to function with any API Server.
| Property | Type | Required | Default | Description |
|---------------------|-------------------|----------|---------|-------------|
| `creationTimestamp` | string | **Yes** | | |
| `finalizers` | string[] | **Yes** | | |
| `labels` | map[string]string | **Yes** | | |
| `resourceVersion` | string | **Yes** | | |
| `uid` | string | **Yes** | | |
| `deletionTimestamp` | string | No | | |
### ExtraFields
extraFields is reserved for any fields that are pulled from the API server metadata but do not have concrete fields in the CUE metadata
| Property | Type | Required | Default | Description |
|----------|------|----------|---------|-------------|
### Spec
| Property | Type | Required | Default | Description |
|---------------|--------|----------|---------|--------------------------------------|
| `title` | string | **Yes** | | Folder title |
| `uid` | string | **Yes** | | Unique folder id. (will be k8s name) |
| `description` | string | No | | Description of the folder. |
### Status
| Property | Type | Required | Default | Description |
|--------------------|----------------------------------------------------------------------------------|----------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `additionalFields` | [object](#additionalfields) | **Yes** | | additionalFields is reserved for future use |
| `operatorStates` | map[string][joinSchema.status.#OperatorState](#joinschema.status.#operatorstate) | No | | operatorStates is a map of operator ID to operator state evaluations.<br/>Any operator which consumes this kind SHOULD add its state evaluation information to this field. |
### AdditionalFields
additionalFields is reserved for future use
| Property | Type | Required | Default | Description |
|----------|------|----------|---------|-------------|
### JoinSchema.Status.#OperatorState
| Property | Type | Required | Default | Description |
|--------------------|--------------------|----------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `lastEvaluation` | string | **Yes** | | lastEvaluation is the ResourceVersion last evaluated |
| `state` | string | **Yes** | | state describes the state of the lastEvaluation.<br/>It is limited to three possible states for machine evaluation.<br/>Possible values are: `success`, `in_progress`, `failed`. |
| `descriptiveState` | string | No | | descriptiveState is an optional more descriptive state field which has no requirements on format |
| `details` | [object](#details) | No | | details contains any extra information that is operator-specific |
### Details
details contains any extra information that is operator-specific
| Property | Type | Required | Default | Description |
|----------|------|----------|---------|-------------|

4
go.sum
View File

@ -1272,10 +1272,6 @@ github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grafana/alerting v0.0.0-20230427200804-f8565cd8b74b h1:SyatotlHGK+05AxICctry09ZEawhE0AasWpOifljH4M=
github.com/grafana/alerting v0.0.0-20230427200804-f8565cd8b74b/go.mod h1:nHfrSTdV7/l74N5/ezqlQ+JwSvIChhN3G5+PjCfwG/E=
github.com/grafana/alerting v0.0.0-20230428094731-e067f119be06 h1:g+J4UGslzpi9Kt+846NDAjGtVyt8K9Lgjj/vUh61yK0=
github.com/grafana/alerting v0.0.0-20230428094731-e067f119be06/go.mod h1:5edgy6tQY4+W2wuJdi8g2GjbVmpJufguy7QGIRl2q4o=
github.com/grafana/alerting v0.0.0-20230428095912-33c5aa68a5ba h1:aNTu22ojw4XY24DYNAuvw8v/5iFUNk2bkdTeeWQ5+0o=
github.com/grafana/alerting v0.0.0-20230428095912-33c5aa68a5ba/go.mod h1:5edgy6tQY4+W2wuJdi8g2GjbVmpJufguy7QGIRl2q4o=
github.com/grafana/codejen v0.0.3 h1:tAWxoTUuhgmEqxJPOLtJoxlPBbMULFwKFOcRsPRPXDw=

View File

@ -0,0 +1,30 @@
package kind
name: "Folder"
maturity: "merged"
description: "A folder is a collection of resources that are grouped together and can share permissions."
lineage: seqs: [
{
schemas: [
//0.0
{
spec: {
// Unique folder id. (will be k8s name)
uid: string
// Folder title
title: string
// Description of the folder.
description?: string
} @cuetsy(kind="interface")
//
// TODO:
// common metadata will soon support setting the parent folder in the metadata
//
},
]
},
]

View File

@ -91,6 +91,9 @@ export {
defaultFieldConfig
} from './veneer/dashboard.types';
// Raw generated types from Folder kind.
export type { Folder } from './raw/folder/x/folder_types.gen';
// Raw generated types from LibraryPanel kind.
export type {
LibraryElementDTOMetaUser,

View File

@ -0,0 +1,24 @@
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
//
// Generated by:
// kinds/gen.go
// Using jennies:
// TSResourceJenny
// LatestMajorsOrXJenny
//
// Run 'make gen-cue' from repository root to regenerate.
export interface Folder {
/**
* Description of the folder.
*/
description?: string;
/**
* Folder title
*/
title: string;
/**
* Unique folder id. (will be k8s name)
*/
uid: string;
}

View File

@ -0,0 +1,17 @@
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
//
// Generated by:
// kinds/gen.go
// Using jennies:
// GoTypesJenny
//
// Run 'make gen-cue' from repository root to regenerate.
package folder
// Resource is the wire representation of Folder. (TODO be better)
type Resource struct {
Metadata Metadata `json:"metadata"`
Spec Spec `json:"spec"`
Status Status `json:"status"`
}

View File

@ -0,0 +1,79 @@
// 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 folder
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/folder"
// 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("folder.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 Folder [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 Folder [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)
}

View File

@ -0,0 +1,42 @@
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
//
// Generated by:
// kinds/gen.go
// Using jennies:
// GoResourceTypes
//
// Run 'make gen-cue' from repository root to regenerate.
package folder
import (
"time"
)
// Metadata defines model for Metadata.
type Metadata struct {
CreatedBy string `json:"createdBy"`
CreationTimestamp time.Time `json:"creationTimestamp"`
DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty"`
// extraFields is reserved for any fields that are pulled from the API server metadata but do not have concrete fields in the CUE metadata
ExtraFields map[string]interface{} `json:"extraFields"`
Finalizers []string `json:"finalizers"`
Labels map[string]string `json:"labels"`
ResourceVersion string `json:"resourceVersion"`
Uid string `json:"uid"`
UpdateTimestamp time.Time `json:"updateTimestamp"`
UpdatedBy string `json:"updatedBy"`
}
// _kubeObjectMetadata is metadata found in a kubernetes object's metadata field.
// It is not exhaustive and only includes fields which may be relevant to a kind's implementation,
// As it is also intended to be generic enough to function with any API Server.
type KubeObjectMetadata struct {
CreationTimestamp time.Time `json:"creationTimestamp"`
DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty"`
Finalizers []string `json:"finalizers"`
Labels map[string]string `json:"labels"`
ResourceVersion string `json:"resourceVersion"`
Uid string `json:"uid"`
}

View File

@ -0,0 +1,22 @@
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
//
// Generated by:
// kinds/gen.go
// Using jennies:
// GoResourceTypes
//
// Run 'make gen-cue' from repository root to regenerate.
package folder
// Spec defines model for Spec.
type Spec struct {
// Description of the folder.
Description *string `json:"description,omitempty"`
// Folder title
Title string `json:"title"`
// Unique folder id. (will be k8s name)
Uid string `json:"uid"`
}

View File

@ -0,0 +1,47 @@
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
//
// Generated by:
// kinds/gen.go
// Using jennies:
// GoResourceTypes
//
// Run 'make gen-cue' from repository root to regenerate.
package folder
// Defines values for OperatorStateState.
const (
OperatorStateStateFailed OperatorStateState = "failed"
OperatorStateStateInProgress OperatorStateState = "in_progress"
OperatorStateStateSuccess OperatorStateState = "success"
)
// OperatorState defines model for OperatorState.
type OperatorState struct {
// descriptiveState is an optional more descriptive state field which has no requirements on format
DescriptiveState *string `json:"descriptiveState,omitempty"`
// details contains any extra information that is operator-specific
Details map[string]interface{} `json:"details,omitempty"`
// lastEvaluation is the ResourceVersion last evaluated
LastEvaluation string `json:"lastEvaluation"`
// state describes the state of the lastEvaluation.
// It is limited to three possible states for machine evaluation.
State OperatorStateState `json:"state"`
}
// OperatorStateState state describes the state of the lastEvaluation.
// It is limited to three possible states for machine evaluation.
type OperatorStateState string
// Status defines model for Status.
type Status struct {
// additionalFields is reserved for future use
AdditionalFields map[string]interface{} `json:"additionalFields"`
// operatorStates is a map of operator ID to operator state evaluations.
// Any operator which consumes this kind SHOULD add its state evaluation information to this field.
OperatorStates map[string]OperatorState `json:"operatorStates,omitempty"`
}

View File

@ -13,6 +13,7 @@ import (
"fmt"
"github.com/grafana/grafana/pkg/kinds/dashboard"
"github.com/grafana/grafana/pkg/kinds/folder"
"github.com/grafana/grafana/pkg/kinds/librarypanel"
"github.com/grafana/grafana/pkg/kinds/playlist"
"github.com/grafana/grafana/pkg/kinds/preferences"
@ -41,6 +42,7 @@ import (
type Base struct {
all []kindsys.Core
dashboard *dashboard.Kind
folder *folder.Kind
librarypanel *librarypanel.Kind
playlist *playlist.Kind
preferences *preferences.Kind
@ -52,6 +54,7 @@ type Base struct {
// type guards
var (
_ kindsys.Core = &dashboard.Kind{}
_ kindsys.Core = &folder.Kind{}
_ kindsys.Core = &librarypanel.Kind{}
_ kindsys.Core = &playlist.Kind{}
_ kindsys.Core = &preferences.Kind{}
@ -65,6 +68,11 @@ func (b *Base) Dashboard() *dashboard.Kind {
return b.dashboard
}
// Folder returns the [kindsys.Interface] implementation for the folder kind.
func (b *Base) Folder() *folder.Kind {
return b.folder
}
// LibraryPanel returns the [kindsys.Interface] implementation for the librarypanel kind.
func (b *Base) LibraryPanel() *librarypanel.Kind {
return b.librarypanel
@ -105,6 +113,12 @@ func doNewBase(rt *thema.Runtime) *Base {
}
reg.all = append(reg.all, reg.dashboard)
reg.folder, err = folder.NewKind(rt)
if err != nil {
panic(fmt.Sprintf("error while initializing the folder Kind: %s", err))
}
reg.all = append(reg.all, reg.folder)
reg.librarypanel, err = librarypanel.NewKind(rt)
if err != nil {
panic(fmt.Sprintf("error while initializing the librarypanel Kind: %s", err))