Schema: Add schema for role+access policies (#68047)

This commit is contained in:
Ryan McKinley
2023-05-24 10:31:57 -07:00
committed by GitHub
parent 3af95bebe1
commit e7da2a179e
34 changed files with 1863 additions and 4 deletions
@@ -0,0 +1,40 @@
// 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 accesspolicy
import (
"github.com/grafana/grafana/pkg/kinds"
)
// Resource is the kubernetes style representation of AccessPolicy. (TODO be better)
type K8sResource = kinds.GrafanaResource[Spec, Status]
// NewResource creates a new instance of the resource with a given name (UID)
func NewK8sResource(name string, s *Spec) K8sResource {
return K8sResource{
Kind: "AccessPolicy",
APIVersion: "v0.0-alpha",
Metadata: kinds.GrafanaResourceMetadata{
Name: name,
Annotations: make(map[string]string),
Labels: make(map[string]string),
},
Spec: s,
}
}
// Resource is the wire representation of AccessPolicy.
// It currently will soon be merged into the k8s flavor (TODO be better)
type Resource struct {
Metadata Metadata `json:"metadata"`
Spec Spec `json:"spec"`
Status Status `json:"status"`
}
@@ -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 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)
}
@@ -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 accesspolicy
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"`
}
@@ -0,0 +1,60 @@
// 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 accesspolicy
// Defines values for RoleRefKind.
const (
RoleRefKindBuiltinRole RoleRefKind = "BuiltinRole"
RoleRefKindRole RoleRefKind = "Role"
RoleRefKindTeam RoleRefKind = "Team"
RoleRefKindUser RoleRefKind = "User"
)
// AccessRule defines model for AccessRule.
type AccessRule struct {
// The kind this rule applies to (dashboars, alert, etc)
Kind string `json:"kind"`
// Specific sub-elements like "alert.rules" or "dashboard.permissions"????
Target *string `json:"target,omitempty"`
// READ, WRITE, CREATE, DELETE, ...
// should move to k8s style verbs like: "get", "list", "watch", "create", "update", "patch", "delete"
Verb string `json:"verb"`
}
// ResourceRef defines model for ResourceRef.
type ResourceRef struct {
Kind string `json:"kind"`
Name string `json:"name"`
}
// RoleRef defines model for RoleRef.
type RoleRef struct {
// Policies can apply to roles, teams, or users
// Applying policies to individual users is supported, but discouraged
Kind RoleRefKind `json:"kind"`
Name string `json:"name"`
Xname string `json:"xname"`
}
// Policies can apply to roles, teams, or users
// Applying policies to individual users is supported, but discouraged
type RoleRefKind string
// Spec defines model for Spec.
type Spec struct {
Role RoleRef `json:"role"`
// The set of rules to apply. Note that * is required to modify
// access policy rules, and that "none" will reject all actions
Rules []AccessRule `json:"rules"`
Scope ResourceRef `json:"scope"`
}
@@ -0,0 +1,74 @@
// 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 accesspolicy
// Defines values for OperatorStateState.
const (
OperatorStateStateFailed OperatorStateState = "failed"
OperatorStateStateInProgress OperatorStateState = "in_progress"
OperatorStateStateSuccess OperatorStateState = "success"
)
// Defines values for StatusOperatorStateState.
const (
StatusOperatorStateStateFailed StatusOperatorStateState = "failed"
StatusOperatorStateStateInProgress StatusOperatorStateState = "in_progress"
StatusOperatorStateStateSuccess StatusOperatorStateState = "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,omitempty"`
// 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]StatusOperatorState `json:"operatorStates,omitempty"`
}
// StatusOperatorState defines model for status.#OperatorState.
type StatusOperatorState 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 StatusOperatorStateState `json:"state"`
}
// StatusOperatorStateState state describes the state of the lastEvaluation.
// It is limited to three possible states for machine evaluation.
type StatusOperatorStateState string
+99
View File
@@ -0,0 +1,99 @@
package accesspolicy
import (
"sort"
"github.com/grafana/grafana/pkg/util"
)
const PermissionsTarget = "permissions"
const AllowAll = "*"
const AllowNone = "none"
func ReduceRules(rules []AccessRule) []AccessRule {
type verbs struct {
Verb map[string][]string
Terminal string
}
kinds := make(map[string]*verbs)
for _, rule := range rules {
if rule.Kind == "" || rule.Verb == "" {
continue // invalid
}
// flip write permission to *
if rule.Target != nil && *rule.Target == PermissionsTarget {
if rule.Verb == "write" {
rule.Verb = AllowAll
}
}
kind, ok := kinds[rule.Kind]
if !ok {
kind = &verbs{
Verb: make(map[string][]string),
}
kinds[rule.Kind] = kind
}
terminal := rule.Verb == AllowAll || rule.Verb == AllowNone
if terminal {
if rule.Kind == AllowAll {
return []AccessRule{rule}
}
kind.Terminal = rule.Verb
} else if kind.Terminal == "" {
targets, ok := kind.Verb[rule.Verb]
if !ok {
targets = []string{}
}
if rule.Target != nil && !contains(targets, *rule.Target) {
targets = append(targets, *rule.Target)
sort.Strings(targets)
}
kind.Verb[rule.Verb] = targets
}
}
results := make([]AccessRule, 0)
for _, kind := range getSortedKeys(kinds) {
verb := kinds[kind]
if verb.Terminal != "" {
results = append(results, AccessRule{Kind: kind, Verb: verb.Terminal})
} else {
for _, v := range getSortedKeys(verb.Verb) {
targets := verb.Verb[v]
if len(targets) == 0 {
results = append(results, AccessRule{Kind: kind, Verb: v})
} else {
for _, t := range targets {
results = append(results, AccessRule{
Kind: kind,
Verb: v,
Target: util.Pointer(t),
})
}
}
}
}
}
return results
}
func getSortedKeys[T any](vals map[string]T) []string {
keys := make([]string, 0, len(vals))
for k := range vals {
keys = append(keys, k)
}
sort.Strings(keys)
return keys
}
func contains[T comparable](s []T, e T) bool {
for _, v := range s {
if v == e {
return true
}
}
return false
}
+68
View File
@@ -0,0 +1,68 @@
package accesspolicy
import (
"encoding/json"
"fmt"
"testing"
"github.com/grafana/grafana/pkg/util"
"github.com/stretchr/testify/require"
)
func TestRuleReducer(t *testing.T) {
t.Run("Check write pointer becomes star", func(t *testing.T) {
rules := ReduceRules([]AccessRule{
{Kind: "dashboard", Verb: "read"},
{Kind: "dashboard", Verb: "write", Target: util.Pointer("permissions")},
{Kind: "dashboard", Verb: "read"},
})
require.Len(t, rules, 1)
require.Equal(t, rules[0], AccessRule{Kind: "dashboard", Verb: "*"})
})
t.Run("Check sort", func(t *testing.T) {
rules := ReduceRules([]AccessRule{
{Kind: "x", Verb: "b"},
{Kind: "x", Verb: "a"},
{Kind: "x", Verb: "a"}, // ignore duplicates
{Kind: "x", Verb: "a"}, // ignore duplicates
{Kind: "x", Verb: "a"}, // ignore duplicates
{Kind: "x", Verb: "a"},
{Kind: "z", Verb: "b"},
{Kind: "AAA", Verb: ""}, // ignore
{Kind: "", Verb: "XXX"}, // ignore
{Kind: "z", Verb: "a"},
{Kind: "y", Verb: "b"},
{Kind: "y", Verb: "a"},
})
out, err := json.MarshalIndent(rules, "", " ")
fmt.Printf("%s", string(out))
require.NoError(t, err)
require.JSONEq(t, `[
{
"kind": "x",
"verb": "a"
},
{
"kind": "x",
"verb": "b"
},
{
"kind": "y",
"verb": "a"
},
{
"kind": "y",
"verb": "b"
},
{
"kind": "z",
"verb": "a"
},
{
"kind": "z",
"verb": "b"
}
]`, string(out))
})
}
+40
View File
@@ -0,0 +1,40 @@
// 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 role
import (
"github.com/grafana/grafana/pkg/kinds"
)
// Resource is the kubernetes style representation of Role. (TODO be better)
type K8sResource = kinds.GrafanaResource[Spec, Status]
// NewResource creates a new instance of the resource with a given name (UID)
func NewK8sResource(name string, s *Spec) K8sResource {
return K8sResource{
Kind: "Role",
APIVersion: "v0.0-alpha",
Metadata: kinds.GrafanaResourceMetadata{
Name: name,
Annotations: make(map[string]string),
Labels: make(map[string]string),
},
Spec: s,
}
}
// Resource is the wire representation of Role.
// It currently will soon be merged into the k8s flavor (TODO be better)
type Resource struct {
Metadata Metadata `json:"metadata"`
Spec Spec `json:"spec"`
Status Status `json:"status"`
}
+79
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 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)
}
+42
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 role
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"`
}
+28
View File
@@ -0,0 +1,28 @@
// 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 role
// Spec defines model for Spec.
type Spec struct {
// Role description
Description *string `json:"description,omitempty"`
// Optional display
DisplayName *string `json:"displayName,omitempty"`
// Name of the team.
GroupName *string `json:"groupName,omitempty"`
// Do not show this role
Hidden bool `json:"hidden"`
// The role identifier `managed:builtins:editor:permissions`
Name string `json:"name"`
}
+74
View File
@@ -0,0 +1,74 @@
// 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 role
// Defines values for OperatorStateState.
const (
OperatorStateStateFailed OperatorStateState = "failed"
OperatorStateStateInProgress OperatorStateState = "in_progress"
OperatorStateStateSuccess OperatorStateState = "success"
)
// Defines values for StatusOperatorStateState.
const (
StatusOperatorStateStateFailed StatusOperatorStateState = "failed"
StatusOperatorStateStateInProgress StatusOperatorStateState = "in_progress"
StatusOperatorStateStateSuccess StatusOperatorStateState = "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,omitempty"`
// 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]StatusOperatorState `json:"operatorStates,omitempty"`
}
// StatusOperatorState defines model for status.#OperatorState.
type StatusOperatorState 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 StatusOperatorStateState `json:"state"`
}
// StatusOperatorStateState state describes the state of the lastEvaluation.
// It is limited to three possible states for machine evaluation.
type StatusOperatorStateState string
+40
View File
@@ -0,0 +1,40 @@
// 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 rolebinding
import (
"github.com/grafana/grafana/pkg/kinds"
)
// Resource is the kubernetes style representation of RoleBinding. (TODO be better)
type K8sResource = kinds.GrafanaResource[Spec, Status]
// NewResource creates a new instance of the resource with a given name (UID)
func NewK8sResource(name string, s *Spec) K8sResource {
return K8sResource{
Kind: "RoleBinding",
APIVersion: "v0.0-alpha",
Metadata: kinds.GrafanaResourceMetadata{
Name: name,
Annotations: make(map[string]string),
Labels: make(map[string]string),
},
Spec: s,
}
}
// Resource is the wire representation of RoleBinding.
// It currently will soon be merged into the k8s flavor (TODO be better)
type Resource struct {
Metadata Metadata `json:"metadata"`
Spec Spec `json:"spec"`
Status Status `json:"status"`
}
@@ -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 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)
}
@@ -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 rolebinding
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"`
}
@@ -0,0 +1,72 @@
// 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 rolebinding
// Defines values for BuiltinRoleRefKind.
const (
BuiltinRoleRefKindBuiltinRole BuiltinRoleRefKind = "BuiltinRole"
)
// Defines values for BuiltinRoleRefName.
const (
BuiltinRoleRefNameAdmin BuiltinRoleRefName = "admin"
BuiltinRoleRefNameEditor BuiltinRoleRefName = "editor"
BuiltinRoleRefNameViewer BuiltinRoleRefName = "viewer"
)
// Defines values for CustomRoleRefKind.
const (
CustomRoleRefKindRole CustomRoleRefKind = "Role"
)
// Defines values for SubjectKind.
const (
SubjectKindTeam SubjectKind = "Team"
SubjectKindUser SubjectKind = "User"
)
// BuiltinRoleRef defines model for BuiltinRoleRef.
type BuiltinRoleRef struct {
Kind BuiltinRoleRefKind `json:"kind"`
Name BuiltinRoleRefName `json:"name"`
}
// BuiltinRoleRefKind defines model for BuiltinRoleRef.Kind.
type BuiltinRoleRefKind string
// BuiltinRoleRefName defines model for BuiltinRoleRef.Name.
type BuiltinRoleRefName string
// CustomRoleRef defines model for CustomRoleRef.
type CustomRoleRef struct {
Kind CustomRoleRefKind `json:"kind"`
Name string `json:"name"`
}
// CustomRoleRefKind defines model for CustomRoleRef.Kind.
type CustomRoleRefKind string
// Subject defines model for Subject.
type Subject struct {
Kind SubjectKind `json:"kind"`
// The team/user identifier name
Name string `json:"name"`
}
// SubjectKind defines model for Subject.Kind.
type SubjectKind string
// Spec defines model for Spec.
type Spec struct {
// The role we are discussing
Role interface{} `json:"role"`
Subject Subject `json:"subject"`
}
@@ -0,0 +1,74 @@
// 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 rolebinding
// Defines values for OperatorStateState.
const (
OperatorStateStateFailed OperatorStateState = "failed"
OperatorStateStateInProgress OperatorStateState = "in_progress"
OperatorStateStateSuccess OperatorStateState = "success"
)
// Defines values for StatusOperatorStateState.
const (
StatusOperatorStateStateFailed StatusOperatorStateState = "failed"
StatusOperatorStateStateInProgress StatusOperatorStateState = "in_progress"
StatusOperatorStateStateSuccess StatusOperatorStateState = "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,omitempty"`
// 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]StatusOperatorState `json:"operatorStates,omitempty"`
}
// StatusOperatorState defines model for status.#OperatorState.
type StatusOperatorState 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 StatusOperatorStateState `json:"state"`
}
// StatusOperatorStateState state describes the state of the lastEvaluation.
// It is limited to three possible states for machine evaluation.
type StatusOperatorStateState string