mirror of https://github.com/grafana/grafana.git
scopes: moves scopes to enterprise (#100746)
Signed-off-by: bergquist <carl.bergquist@gmail.com>
This commit is contained in:
parent
0290da6aaa
commit
79c0e5e3ec
|
|
@ -617,6 +617,11 @@ github.com/grafana/cog v0.0.23/go.mod h1:jrS9indvWuDs60RHEZpLaAkmZdgyoLKMOEUT0ji
|
|||
github.com/grafana/go-gelf/v2 v2.0.1 h1:BOChP0h/jLeD+7F9mL7tq10xVkDG15he3T1zHuQaWak=
|
||||
github.com/grafana/go-gelf/v2 v2.0.1/go.mod h1:lexHie0xzYGwCgiRGcvZ723bSNyNI8ZRD4s0CLobh90=
|
||||
github.com/grafana/grafana/apps/advisor v0.0.0-20250220154326-6e5de80ef295/go.mod h1:9I1dKV3Dqr0NPR9Af0WJGxOytp5/6W3JLiNChOz8r+c=
|
||||
github.com/grafana/grafana/apps/advisor v0.0.0-20250220163425-b4c4b9abbdc8/go.mod h1:9I1dKV3Dqr0NPR9Af0WJGxOytp5/6W3JLiNChOz8r+c=
|
||||
github.com/grafana/grafana/apps/alerting/notifications v0.0.0-20250220163425-b4c4b9abbdc8/go.mod h1:dHhFF484qs1cmdIShKCB3kl+tMJyc4yuwgTQ3Afz37o=
|
||||
github.com/grafana/grafana/apps/investigations v0.0.0-20250220163425-b4c4b9abbdc8/go.mod h1:ygFcJP2McdSeMJVj/3YrKafZMc/lZBsp54HO51MtJYw=
|
||||
github.com/grafana/grafana/apps/playlist v0.0.0-20250220164708-c8d4ff28a450/go.mod h1:KKIsWpbv88Lwwcvdjon73zFL7vNJvuXLtsSoUjJErTw=
|
||||
github.com/grafana/grafana/pkg/build v0.0.0-20250220114259-be81314e2118/go.mod h1:STVpVboMYeBAfyn6Zw6XHhTHqUxzMy7pzRiVgk1l0W0=
|
||||
github.com/grafana/tail v0.0.0-20230510142333-77b18831edf0 h1:bjh0PVYSVVFxzINqPFYJmAmJNrWPgnVjuSdYJGHmtFU=
|
||||
github.com/grafana/tail v0.0.0-20230510142333-77b18831edf0/go.mod h1:7t5XR+2IA8P2qggOAHTj/GCZfoLBle3OvNSYh1VkRBU=
|
||||
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA=
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
// +k8s:deepcopy-gen=package
|
||||
// +k8s:openapi-gen=true
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
// +groupName=common.grafana.app
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
package v0alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// Similar to
|
||||
// https://dev-k8sref-io.web.app/docs/common-definitions/objectreference-/
|
||||
// ObjectReference contains enough information to let you inspect or modify the referred object.
|
||||
|
|
@ -15,3 +19,41 @@ type ObjectReference struct {
|
|||
// APIVersion is the version of the API group that contains the referred object.
|
||||
APIVersion string `json:"apiVersion,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type Scope struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ScopeSpec `json:"spec,omitempty"`
|
||||
}
|
||||
|
||||
type ScopeSpec struct {
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
|
||||
// +listType=atomic
|
||||
Filters []ScopeFilter `json:"filters"`
|
||||
}
|
||||
|
||||
type ScopeFilter struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
// Values is used for operators that require multiple values (e.g. one-of and not-one-of).
|
||||
Values []string `json:"values,omitempty"`
|
||||
Operator FilterOperator `json:"operator"`
|
||||
}
|
||||
|
||||
// Type of the filter operator.
|
||||
// +enum
|
||||
type FilterOperator string
|
||||
|
||||
// Defines values for FilterOperator.
|
||||
const (
|
||||
FilterOperatorEquals FilterOperator = "equals"
|
||||
FilterOperatorNotEquals FilterOperator = "not-equals"
|
||||
FilterOperatorRegexMatch FilterOperator = "regex-match"
|
||||
FilterOperatorRegexNotMatch FilterOperator = "regex-not-match"
|
||||
FilterOperatorOneOf FilterOperator = "one-of"
|
||||
FilterOperatorNotOneOf FilterOperator = "not-one-of"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,99 @@
|
|||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ObjectReference) DeepCopyInto(out *ObjectReference) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectReference.
|
||||
func (in *ObjectReference) DeepCopy() *ObjectReference {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ObjectReference)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Scope) DeepCopyInto(out *Scope) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Scope.
|
||||
func (in *Scope) DeepCopy() *Scope {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Scope)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *Scope) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ScopeFilter) DeepCopyInto(out *ScopeFilter) {
|
||||
*out = *in
|
||||
if in.Values != nil {
|
||||
in, out := &in.Values, &out.Values
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeFilter.
|
||||
func (in *ScopeFilter) DeepCopy() *ScopeFilter {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ScopeFilter)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ScopeSpec) DeepCopyInto(out *ScopeSpec) {
|
||||
*out = *in
|
||||
if in.Filters != nil {
|
||||
in, out := &in.Filters, &out.Filters
|
||||
*out = make([]ScopeFilter, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeSpec.
|
||||
func (in *ScopeSpec) DeepCopy() *ScopeSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ScopeSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
|
@ -16,6 +16,9 @@ import (
|
|||
func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition {
|
||||
return map[string]common.OpenAPIDefinition{
|
||||
"github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.ObjectReference": schema_apimachinery_apis_common_v0alpha1_ObjectReference(ref),
|
||||
"github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Scope": schema_apimachinery_apis_common_v0alpha1_Scope(ref),
|
||||
"github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.ScopeFilter": schema_apimachinery_apis_common_v0alpha1_ScopeFilter(ref),
|
||||
"github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.ScopeSpec": schema_apimachinery_apis_common_v0alpha1_ScopeSpec(ref),
|
||||
"github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured": Unstructured{}.OpenAPIDefinition(),
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1.APIGroup": schema_pkg_apis_meta_v1_APIGroup(ref),
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1.APIGroupList": schema_pkg_apis_meta_v1_APIGroupList(ref),
|
||||
|
|
@ -118,6 +121,144 @@ func schema_apimachinery_apis_common_v0alpha1_ObjectReference(ref common.Referen
|
|||
}
|
||||
}
|
||||
|
||||
func schema_apimachinery_apis_common_v0alpha1_Scope(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"kind": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"apiVersion": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"metadata": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"),
|
||||
},
|
||||
},
|
||||
"spec": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.ScopeSpec"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.ScopeSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_apimachinery_apis_common_v0alpha1_ScopeFilter(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"key": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"value": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"values": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Values is used for operators that require multiple values (e.g. one-of and not-one-of).",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"operator": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Possible enum values:\n - `\"equals\"`\n - `\"not-equals\"`\n - `\"not-one-of\"`\n - `\"one-of\"`\n - `\"regex-match\"`\n - `\"regex-not-match\"`",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
Enum: []interface{}{"equals", "not-equals", "not-one-of", "one-of", "regex-match", "regex-not-match"},
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"key", "value", "operator"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_apimachinery_apis_common_v0alpha1_ScopeSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"title": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"description": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"filters": {
|
||||
VendorExtensible: spec.VendorExtensible{
|
||||
Extensions: spec.Extensions{
|
||||
"x-kubernetes-list-type": "atomic",
|
||||
},
|
||||
},
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.ScopeFilter"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"title", "description", "filters"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.ScopeFilter"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_meta_v1_APIGroup(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1,ScopeFilter,Values
|
||||
API rule violation: names_match,github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1,Unstructured,Object
|
||||
API rule violation: names_match,k8s.io/apimachinery/pkg/apis/meta/v1,APIResourceList,APIResources
|
||||
API rule violation: names_match,k8s.io/apimachinery/pkg/apis/meta/v1,Duration,Duration
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
// +k8s:deepcopy-gen=package
|
||||
// +k8s:openapi-gen=true
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
// +groupName=scope.grafana.app
|
||||
|
||||
package v0alpha1 // import "github.com/grafana/grafana/pkg/apis/scope/v0alpha1"
|
||||
|
|
@ -1,139 +0,0 @@
|
|||
package v0alpha1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
const (
|
||||
GROUP = "scope.grafana.app"
|
||||
VERSION = "v0alpha1"
|
||||
APIVERSION = GROUP + "/" + VERSION
|
||||
)
|
||||
|
||||
var ScopeResourceInfo = utils.NewResourceInfo(GROUP, VERSION,
|
||||
"scopes", "scope", "Scope",
|
||||
func() runtime.Object { return &Scope{} },
|
||||
func() runtime.Object { return &ScopeList{} },
|
||||
utils.TableColumns{
|
||||
Definition: []metav1.TableColumnDefinition{
|
||||
{Name: "Name", Type: "string", Format: "name"},
|
||||
{Name: "Created At", Type: "date"},
|
||||
{Name: "Title", Type: "string"},
|
||||
{Name: "Filters", Type: "array"},
|
||||
},
|
||||
Reader: func(obj any) ([]interface{}, error) {
|
||||
m, ok := obj.(*Scope)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("expected scope")
|
||||
}
|
||||
return []interface{}{
|
||||
m.Name,
|
||||
m.CreationTimestamp.UTC().Format(time.RFC3339),
|
||||
m.Spec.Title,
|
||||
m.Spec.Filters,
|
||||
}, nil
|
||||
},
|
||||
}, // default table converter
|
||||
)
|
||||
|
||||
var ScopeDashboardBindingResourceInfo = utils.NewResourceInfo(GROUP, VERSION,
|
||||
"scopedashboardbindings", "scopedashboardbinding", "ScopeDashboardBinding",
|
||||
func() runtime.Object { return &ScopeDashboardBinding{} },
|
||||
func() runtime.Object { return &ScopeDashboardBindingList{} },
|
||||
utils.TableColumns{
|
||||
Definition: []metav1.TableColumnDefinition{
|
||||
{Name: "Name", Type: "string", Format: "name"},
|
||||
{Name: "Created At", Type: "date"},
|
||||
{Name: "Dashboard", Type: "string"},
|
||||
{Name: "Scope", Type: "string"},
|
||||
},
|
||||
Reader: func(obj any) ([]interface{}, error) {
|
||||
m, ok := obj.(*ScopeDashboardBinding)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("expected scope dashboard binding")
|
||||
}
|
||||
return []interface{}{
|
||||
m.Name,
|
||||
m.CreationTimestamp.UTC().Format(time.RFC3339),
|
||||
m.Spec.Dashboard,
|
||||
m.Spec.Scope,
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
var ScopeNodeResourceInfo = utils.NewResourceInfo(GROUP, VERSION,
|
||||
"scopenodes", "scopenode", "ScopeNode",
|
||||
func() runtime.Object { return &ScopeNode{} },
|
||||
func() runtime.Object { return &ScopeNodeList{} },
|
||||
utils.TableColumns{
|
||||
Definition: []metav1.TableColumnDefinition{
|
||||
{Name: "Name", Type: "string", Format: "name"},
|
||||
{Name: "Created At", Type: "date"},
|
||||
{Name: "Title", Type: "string"},
|
||||
{Name: "Parent Name", Type: "string"},
|
||||
{Name: "Node Type", Type: "string"},
|
||||
{Name: "Link Type", Type: "string"},
|
||||
{Name: "Link ID", Type: "string"},
|
||||
},
|
||||
Reader: func(obj any) ([]interface{}, error) {
|
||||
m, ok := obj.(*ScopeNode)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("expected scope node")
|
||||
}
|
||||
return []interface{}{
|
||||
m.Name,
|
||||
m.CreationTimestamp.UTC().Format(time.RFC3339),
|
||||
m.Spec.Title,
|
||||
m.Spec.ParentName,
|
||||
m.Spec.NodeType,
|
||||
m.Spec.LinkType,
|
||||
m.Spec.LinkID,
|
||||
}, nil
|
||||
},
|
||||
}, // default table converter
|
||||
)
|
||||
|
||||
var (
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
SchemeGroupVersion = schema.GroupVersion{Group: GROUP, Version: VERSION}
|
||||
InternalGroupVersion = schema.GroupVersion{Group: GROUP, Version: runtime.APIVersionInternal}
|
||||
|
||||
// SchemaBuilder is used by standard codegen
|
||||
SchemeBuilder runtime.SchemeBuilder
|
||||
localSchemeBuilder = &SchemeBuilder
|
||||
AddToScheme = localSchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
func init() {
|
||||
localSchemeBuilder.Register(func(s *runtime.Scheme) error {
|
||||
return AddKnownTypes(SchemeGroupVersion, s)
|
||||
})
|
||||
}
|
||||
|
||||
// Adds the list of known types to the given scheme.
|
||||
func AddKnownTypes(gv schema.GroupVersion, scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(gv,
|
||||
&Scope{},
|
||||
&ScopeList{},
|
||||
&ScopeDashboardBinding{},
|
||||
&ScopeDashboardBindingList{},
|
||||
&ScopeNode{},
|
||||
&ScopeNodeList{},
|
||||
&FindScopeNodeChildrenResults{},
|
||||
&FindScopeDashboardBindingsResults{},
|
||||
)
|
||||
//metav1.AddToGroupVersion(scheme, gv)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
|
@ -1,167 +0,0 @@
|
|||
package v0alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
/*
|
||||
Please keep pkg/promlib/models/query.go and pkg/promlib/models/scope.go in sync
|
||||
with this file until this package is out of the grafana/grafana module.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type Scope struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ScopeSpec `json:"spec,omitempty"`
|
||||
}
|
||||
|
||||
type ScopeSpec struct {
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
|
||||
// +listType=atomic
|
||||
Filters []ScopeFilter `json:"filters"`
|
||||
}
|
||||
|
||||
type ScopeFilter struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
// Values is used for operators that require multiple values (e.g. one-of and not-one-of).
|
||||
Values []string `json:"values,omitempty"`
|
||||
Operator FilterOperator `json:"operator"`
|
||||
}
|
||||
|
||||
// Type of the filter operator.
|
||||
// +enum
|
||||
type FilterOperator string
|
||||
|
||||
// Defines values for FilterOperator.
|
||||
const (
|
||||
FilterOperatorEquals FilterOperator = "equals"
|
||||
FilterOperatorNotEquals FilterOperator = "not-equals"
|
||||
FilterOperatorRegexMatch FilterOperator = "regex-match"
|
||||
FilterOperatorRegexNotMatch FilterOperator = "regex-not-match"
|
||||
FilterOperatorOneOf FilterOperator = "one-of"
|
||||
FilterOperatorNotOneOf FilterOperator = "not-one-of"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type ScopeList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []Scope `json:"items,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type ScopeDashboardBinding struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ScopeDashboardBindingSpec `json:"spec,omitempty"`
|
||||
Status ScopeDashboardBindingStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type ScopeDashboardBindingList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []ScopeDashboardBinding `json:"items,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type FindScopeDashboardBindingsResults struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
Items []ScopeDashboardBinding `json:"items,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type ScopeNode struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ScopeNodeSpec `json:"spec,omitempty"`
|
||||
}
|
||||
|
||||
type ScopeDashboardBindingSpec struct {
|
||||
Dashboard string `json:"dashboard"`
|
||||
Scope string `json:"scope"`
|
||||
}
|
||||
|
||||
// Type of the item.
|
||||
// +enum
|
||||
// ScopeDashboardBindingStatus contains derived information about a ScopeDashboardBinding.
|
||||
type ScopeDashboardBindingStatus struct {
|
||||
// DashboardTitle should be populated and update from the dashboard
|
||||
DashboardTitle string `json:"dashboardTitle"`
|
||||
|
||||
// Groups is used for the grouping of dashboards that are suggested based
|
||||
// on a scope. The source of truth for this information has not been
|
||||
// determined yet.
|
||||
Groups []string `json:"groups,omitempty"`
|
||||
|
||||
// DashboardTitleConditions is a list of conditions that are used to determine if the dashboard title is valid.
|
||||
// +optional
|
||||
// +listType=map
|
||||
// +listMapKey=type
|
||||
DashboardTitleConditions []metav1.Condition `json:"dashboardTitleConditions,omitempty"`
|
||||
|
||||
// DashboardTitleConditions is a list of conditions that are used to determine if the list of groups is valid.
|
||||
// +optional
|
||||
// +listType=map
|
||||
// +listMapKey=type
|
||||
GroupsConditions []metav1.Condition `json:"groupsConditions,omitempty"`
|
||||
}
|
||||
|
||||
type NodeType string
|
||||
|
||||
// Defines values for ItemType.
|
||||
const (
|
||||
NodeTypeContainer NodeType = "container"
|
||||
NodeTypeLeaf NodeType = "leaf"
|
||||
)
|
||||
|
||||
// Type of the item.
|
||||
// +enum
|
||||
type LinkType string
|
||||
|
||||
// Defines values for ItemType.
|
||||
const (
|
||||
LinkTypeScope LinkType = "scope"
|
||||
)
|
||||
|
||||
type ScopeNodeSpec struct {
|
||||
//+optional
|
||||
ParentName string `json:"parentName,omitempty"`
|
||||
|
||||
NodeType NodeType `json:"nodeType"` // container | leaf
|
||||
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description,omitempty"`
|
||||
DisableMultiSelect bool `json:"disableMultiSelect"`
|
||||
|
||||
LinkType LinkType `json:"linkType,omitempty"` // scope (later more things)
|
||||
LinkID string `json:"linkId,omitempty"` // the k8s name
|
||||
// ?? should this be a slice of links
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type ScopeNodeList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []ScopeNode `json:"items,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type FindScopeNodeChildrenResults struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []ScopeNode `json:"items,omitempty"`
|
||||
}
|
||||
|
|
@ -1,370 +0,0 @@
|
|||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *FindScopeDashboardBindingsResults) DeepCopyInto(out *FindScopeDashboardBindingsResults) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]ScopeDashboardBinding, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FindScopeDashboardBindingsResults.
|
||||
func (in *FindScopeDashboardBindingsResults) DeepCopy() *FindScopeDashboardBindingsResults {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(FindScopeDashboardBindingsResults)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *FindScopeDashboardBindingsResults) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *FindScopeNodeChildrenResults) DeepCopyInto(out *FindScopeNodeChildrenResults) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]ScopeNode, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FindScopeNodeChildrenResults.
|
||||
func (in *FindScopeNodeChildrenResults) DeepCopy() *FindScopeNodeChildrenResults {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(FindScopeNodeChildrenResults)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *FindScopeNodeChildrenResults) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Scope) DeepCopyInto(out *Scope) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Scope.
|
||||
func (in *Scope) DeepCopy() *Scope {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Scope)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *Scope) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ScopeDashboardBinding) DeepCopyInto(out *ScopeDashboardBinding) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
out.Spec = in.Spec
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeDashboardBinding.
|
||||
func (in *ScopeDashboardBinding) DeepCopy() *ScopeDashboardBinding {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ScopeDashboardBinding)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ScopeDashboardBinding) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ScopeDashboardBindingList) DeepCopyInto(out *ScopeDashboardBindingList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]ScopeDashboardBinding, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeDashboardBindingList.
|
||||
func (in *ScopeDashboardBindingList) DeepCopy() *ScopeDashboardBindingList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ScopeDashboardBindingList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ScopeDashboardBindingList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ScopeDashboardBindingSpec) DeepCopyInto(out *ScopeDashboardBindingSpec) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeDashboardBindingSpec.
|
||||
func (in *ScopeDashboardBindingSpec) DeepCopy() *ScopeDashboardBindingSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ScopeDashboardBindingSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ScopeDashboardBindingStatus) DeepCopyInto(out *ScopeDashboardBindingStatus) {
|
||||
*out = *in
|
||||
if in.Groups != nil {
|
||||
in, out := &in.Groups, &out.Groups
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.DashboardTitleConditions != nil {
|
||||
in, out := &in.DashboardTitleConditions, &out.DashboardTitleConditions
|
||||
*out = make([]v1.Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.GroupsConditions != nil {
|
||||
in, out := &in.GroupsConditions, &out.GroupsConditions
|
||||
*out = make([]v1.Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeDashboardBindingStatus.
|
||||
func (in *ScopeDashboardBindingStatus) DeepCopy() *ScopeDashboardBindingStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ScopeDashboardBindingStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ScopeFilter) DeepCopyInto(out *ScopeFilter) {
|
||||
*out = *in
|
||||
if in.Values != nil {
|
||||
in, out := &in.Values, &out.Values
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeFilter.
|
||||
func (in *ScopeFilter) DeepCopy() *ScopeFilter {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ScopeFilter)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ScopeList) DeepCopyInto(out *ScopeList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]Scope, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeList.
|
||||
func (in *ScopeList) DeepCopy() *ScopeList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ScopeList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ScopeList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ScopeNode) DeepCopyInto(out *ScopeNode) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
out.Spec = in.Spec
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeNode.
|
||||
func (in *ScopeNode) DeepCopy() *ScopeNode {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ScopeNode)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ScopeNode) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ScopeNodeList) DeepCopyInto(out *ScopeNodeList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]ScopeNode, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeNodeList.
|
||||
func (in *ScopeNodeList) DeepCopy() *ScopeNodeList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ScopeNodeList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ScopeNodeList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ScopeNodeSpec) DeepCopyInto(out *ScopeNodeSpec) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeNodeSpec.
|
||||
func (in *ScopeNodeSpec) DeepCopy() *ScopeNodeSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ScopeNodeSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ScopeSpec) DeepCopyInto(out *ScopeSpec) {
|
||||
*out = *in
|
||||
if in.Filters != nil {
|
||||
in, out := &in.Filters, &out.Filters
|
||||
*out = make([]ScopeFilter, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeSpec.
|
||||
func (in *ScopeSpec) DeepCopy() *ScopeSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ScopeSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
// Code generated by defaulter-gen. DO NOT EDIT.
|
||||
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// RegisterDefaults adds defaulters functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
// All generated defaulters are covering - they call all nested defaulters.
|
||||
func RegisterDefaults(scheme *runtime.Scheme) error {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -1,661 +0,0 @@
|
|||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
// Code generated by openapi-gen. DO NOT EDIT.
|
||||
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
common "k8s.io/kube-openapi/pkg/common"
|
||||
spec "k8s.io/kube-openapi/pkg/validation/spec"
|
||||
)
|
||||
|
||||
func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition {
|
||||
return map[string]common.OpenAPIDefinition{
|
||||
"github.com/grafana/grafana/pkg/apis/scope/v0alpha1.FindScopeDashboardBindingsResults": schema_pkg_apis_scope_v0alpha1_FindScopeDashboardBindingsResults(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/scope/v0alpha1.FindScopeNodeChildrenResults": schema_pkg_apis_scope_v0alpha1_FindScopeNodeChildrenResults(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/scope/v0alpha1.Scope": schema_pkg_apis_scope_v0alpha1_Scope(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboardBinding": schema_pkg_apis_scope_v0alpha1_ScopeDashboardBinding(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboardBindingList": schema_pkg_apis_scope_v0alpha1_ScopeDashboardBindingList(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboardBindingSpec": schema_pkg_apis_scope_v0alpha1_ScopeDashboardBindingSpec(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboardBindingStatus": schema_pkg_apis_scope_v0alpha1_ScopeDashboardBindingStatus(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeFilter": schema_pkg_apis_scope_v0alpha1_ScopeFilter(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeList": schema_pkg_apis_scope_v0alpha1_ScopeList(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeNode": schema_pkg_apis_scope_v0alpha1_ScopeNode(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeNodeList": schema_pkg_apis_scope_v0alpha1_ScopeNodeList(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeNodeSpec": schema_pkg_apis_scope_v0alpha1_ScopeNodeSpec(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeSpec": schema_pkg_apis_scope_v0alpha1_ScopeSpec(ref),
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_scope_v0alpha1_FindScopeDashboardBindingsResults(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"kind": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"apiVersion": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"items": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboardBinding"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"message": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboardBinding"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_scope_v0alpha1_FindScopeNodeChildrenResults(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"kind": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"apiVersion": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"metadata": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"),
|
||||
},
|
||||
},
|
||||
"items": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeNode"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeNode", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_scope_v0alpha1_Scope(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"kind": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"apiVersion": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"metadata": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"),
|
||||
},
|
||||
},
|
||||
"spec": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeSpec"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_scope_v0alpha1_ScopeDashboardBinding(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"kind": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"apiVersion": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"metadata": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"),
|
||||
},
|
||||
},
|
||||
"spec": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboardBindingSpec"),
|
||||
},
|
||||
},
|
||||
"status": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboardBindingStatus"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboardBindingSpec", "github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboardBindingStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_scope_v0alpha1_ScopeDashboardBindingList(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"kind": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"apiVersion": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"metadata": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"),
|
||||
},
|
||||
},
|
||||
"items": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboardBinding"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboardBinding", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_scope_v0alpha1_ScopeDashboardBindingSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"dashboard": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"scope": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"dashboard", "scope"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_scope_v0alpha1_ScopeDashboardBindingStatus(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Type of the item. ScopeDashboardBindingStatus contains derived information about a ScopeDashboardBinding.",
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"dashboardTitle": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "DashboardTitle should be populated and update from the dashboard",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"groups": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Groups is used for the grouping of dashboards that are suggested based on a scope. The source of truth for this information has not been determined yet.",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"dashboardTitleConditions": {
|
||||
VendorExtensible: spec.VendorExtensible{
|
||||
Extensions: spec.Extensions{
|
||||
"x-kubernetes-list-map-keys": []interface{}{
|
||||
"type",
|
||||
},
|
||||
"x-kubernetes-list-type": "map",
|
||||
},
|
||||
},
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "DashboardTitleConditions is a list of conditions that are used to determine if the dashboard title is valid.",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Condition"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"groupsConditions": {
|
||||
VendorExtensible: spec.VendorExtensible{
|
||||
Extensions: spec.Extensions{
|
||||
"x-kubernetes-list-map-keys": []interface{}{
|
||||
"type",
|
||||
},
|
||||
"x-kubernetes-list-type": "map",
|
||||
},
|
||||
},
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "DashboardTitleConditions is a list of conditions that are used to determine if the list of groups is valid.",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Condition"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"dashboardTitle"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1.Condition"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_scope_v0alpha1_ScopeFilter(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"key": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"value": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"values": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Values is used for operators that require multiple values (e.g. one-of and not-one-of).",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"operator": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Possible enum values:\n - `\"equals\"`\n - `\"not-equals\"`\n - `\"not-one-of\"`\n - `\"one-of\"`\n - `\"regex-match\"`\n - `\"regex-not-match\"`",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
Enum: []interface{}{"equals", "not-equals", "not-one-of", "one-of", "regex-match", "regex-not-match"},
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"key", "value", "operator"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_scope_v0alpha1_ScopeList(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"kind": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"apiVersion": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"metadata": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"),
|
||||
},
|
||||
},
|
||||
"items": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apis/scope/v0alpha1.Scope"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/pkg/apis/scope/v0alpha1.Scope", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_scope_v0alpha1_ScopeNode(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"kind": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"apiVersion": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"metadata": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"),
|
||||
},
|
||||
},
|
||||
"spec": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeNodeSpec"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeNodeSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_scope_v0alpha1_ScopeNodeList(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"kind": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"apiVersion": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"metadata": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"),
|
||||
},
|
||||
},
|
||||
"items": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeNode"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeNode", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_scope_v0alpha1_ScopeNodeSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"parentName": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"nodeType": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"title": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"description": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"disableMultiSelect": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: false,
|
||||
Type: []string{"boolean"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"linkType": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Possible enum values:\n - `\"scope\"`",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
Enum: []interface{}{"scope"},
|
||||
},
|
||||
},
|
||||
"linkId": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "scope (later more things)",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"nodeType", "title", "disableMultiSelect"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_scope_v0alpha1_ScopeSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"title": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"description": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"filters": {
|
||||
VendorExtensible: spec.VendorExtensible{
|
||||
Extensions: spec.Extensions{
|
||||
"x-kubernetes-list-type": "atomic",
|
||||
},
|
||||
},
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeFilter"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"title", "description", "filters"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeFilter"},
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/scope/v0alpha1,FindScopeDashboardBindingsResults,Items
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/scope/v0alpha1,ScopeDashboardBindingStatus,Groups
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/scope/v0alpha1,ScopeFilter,Values
|
||||
API rule violation: names_match,github.com/grafana/grafana/pkg/apis/scope/v0alpha1,ScopeNodeSpec,LinkID
|
||||
|
|
@ -13,7 +13,6 @@ import (
|
|||
"github.com/grafana/grafana/pkg/registry/apis/iam"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/provisioning"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/query"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/scope"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/userstorage"
|
||||
)
|
||||
|
||||
|
|
@ -31,7 +30,6 @@ func ProvideRegistryServiceSink(
|
|||
_ *datasource.DataSourceAPIBuilder,
|
||||
_ *folders.FolderAPIBuilder,
|
||||
_ *iam.IdentityAccessManagementAPIBuilder,
|
||||
_ *scope.ScopeAPIBuilder,
|
||||
_ *query.QueryAPIBuilder,
|
||||
_ *notifications.NotificationsAPIBuilder,
|
||||
_ *userstorage.UserStorageAPIBuilder,
|
||||
|
|
|
|||
|
|
@ -1,113 +0,0 @@
|
|||
package scope
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
|
||||
scope "github.com/grafana/grafana/pkg/apis/scope/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
)
|
||||
|
||||
var logger = log.New("find-scopenode")
|
||||
|
||||
type findREST struct {
|
||||
scopeNodeStorage *storage
|
||||
}
|
||||
|
||||
var (
|
||||
_ rest.Storage = (*findREST)(nil)
|
||||
_ rest.SingularNameProvider = (*findREST)(nil)
|
||||
_ rest.Connecter = (*findREST)(nil)
|
||||
_ rest.Scoper = (*findREST)(nil)
|
||||
_ rest.StorageMetadata = (*findREST)(nil)
|
||||
)
|
||||
|
||||
func (r *findREST) New() runtime.Object {
|
||||
// This is added as the "ResponseType" regarless what ProducesObject() says :)
|
||||
return &scope.FindScopeNodeChildrenResults{}
|
||||
}
|
||||
|
||||
func (r *findREST) Destroy() {}
|
||||
|
||||
func (r *findREST) NamespaceScoped() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (r *findREST) GetSingularName() string {
|
||||
return "FindScopeNodeChildrenResults" // Used for the
|
||||
}
|
||||
|
||||
func (r *findREST) ProducesMIMETypes(verb string) []string {
|
||||
return []string{"application/json"} // and parquet!
|
||||
}
|
||||
|
||||
func (r *findREST) ProducesObject(verb string) interface{} {
|
||||
return &scope.FindScopeNodeChildrenResults{}
|
||||
}
|
||||
|
||||
func (r *findREST) ConnectMethods() []string {
|
||||
return []string{"GET"}
|
||||
}
|
||||
|
||||
func (r *findREST) NewConnectOptions() (runtime.Object, bool, string) {
|
||||
return nil, false, "" // true means you can use the trailing path as a variable
|
||||
}
|
||||
|
||||
func (r *findREST) Connect(ctx context.Context, name string, opts runtime.Object, responder rest.Responder) (http.Handler, error) {
|
||||
// See: /pkg/services/apiserver/builder/helper.go#L34
|
||||
// The name is set with a rewriter hack
|
||||
if name != "name" {
|
||||
return nil, errors.NewNotFound(schema.GroupResource{}, name)
|
||||
}
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
parent := req.URL.Query().Get("parent")
|
||||
query := req.URL.Query().Get("query")
|
||||
results := &scope.FindScopeNodeChildrenResults{}
|
||||
|
||||
raw, err := r.scopeNodeStorage.List(ctx, &internalversion.ListOptions{
|
||||
Limit: 10000,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
responder.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
all, ok := raw.(*scope.ScopeNodeList)
|
||||
|
||||
if !ok {
|
||||
responder.Error(fmt.Errorf("expected ScopeNodeList"))
|
||||
return
|
||||
}
|
||||
|
||||
for _, item := range all.Items {
|
||||
filterAndAppendItem(item, parent, query, results)
|
||||
}
|
||||
|
||||
logger.FromContext(req.Context()).Debug("find scopenode", "raw", len(all.Items), "filtered", len(results.Items))
|
||||
|
||||
responder.Object(200, results)
|
||||
}), nil
|
||||
}
|
||||
|
||||
func filterAndAppendItem(item scope.ScopeNode, parent string, query string, results *scope.FindScopeNodeChildrenResults) {
|
||||
if parent != item.Spec.ParentName {
|
||||
return // Someday this will have an index in raw storage on parentName
|
||||
}
|
||||
|
||||
// skip if query is passed and title doesn't contain the query.
|
||||
if query != "" && !strings.Contains(item.Spec.Title, query) {
|
||||
return
|
||||
}
|
||||
|
||||
results.Items = append(results.Items, item)
|
||||
}
|
||||
|
|
@ -1,106 +0,0 @@
|
|||
package scope
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
scope "github.com/grafana/grafana/pkg/apis/scope/v0alpha1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
)
|
||||
|
||||
type findScopeDashboardsREST struct {
|
||||
scopeDashboardStorage *storage
|
||||
}
|
||||
|
||||
var (
|
||||
_ rest.Storage = (*findScopeDashboardsREST)(nil)
|
||||
_ rest.SingularNameProvider = (*findScopeDashboardsREST)(nil)
|
||||
_ rest.Connecter = (*findScopeDashboardsREST)(nil)
|
||||
_ rest.Scoper = (*findScopeDashboardsREST)(nil)
|
||||
_ rest.StorageMetadata = (*findScopeDashboardsREST)(nil)
|
||||
)
|
||||
|
||||
func (f *findScopeDashboardsREST) New() runtime.Object {
|
||||
return &scope.FindScopeDashboardBindingsResults{}
|
||||
}
|
||||
|
||||
func (f *findScopeDashboardsREST) Destroy() {}
|
||||
|
||||
func (f *findScopeDashboardsREST) NamespaceScoped() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (f *findScopeDashboardsREST) GetSingularName() string {
|
||||
return "FindScopeDashboardsResult" // not sure if this is actually used, but it is required to exist
|
||||
}
|
||||
|
||||
func (f *findScopeDashboardsREST) ProducesMIMETypes(verb string) []string {
|
||||
return []string{"application/json"} // and parquet!
|
||||
}
|
||||
|
||||
func (f *findScopeDashboardsREST) ProducesObject(verb string) interface{} {
|
||||
return &scope.FindScopeDashboardBindingsResults{}
|
||||
}
|
||||
|
||||
func (f *findScopeDashboardsREST) ConnectMethods() []string {
|
||||
return []string{"GET"}
|
||||
}
|
||||
|
||||
func (f *findScopeDashboardsREST) NewConnectOptions() (runtime.Object, bool, string) {
|
||||
return nil, false, "" // true means you can use the trailing path as a variable
|
||||
}
|
||||
|
||||
func (f *findScopeDashboardsREST) Connect(ctx context.Context, name string, opts runtime.Object, responder rest.Responder) (http.Handler, error) {
|
||||
// See: /pkg/services/apiserver/builder/helper.go#L34
|
||||
// The name is set with a rewriter hack
|
||||
if name != "name" {
|
||||
return nil, errors.NewNotFound(schema.GroupResource{}, name)
|
||||
}
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
raw, err := f.scopeDashboardStorage.List(ctx, &internalversion.ListOptions{
|
||||
Limit: 10000,
|
||||
})
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
return
|
||||
}
|
||||
all, ok := raw.(*scope.ScopeDashboardBindingList)
|
||||
if !ok {
|
||||
w.WriteHeader(500)
|
||||
return
|
||||
}
|
||||
|
||||
scopes := req.URL.Query()["scope"]
|
||||
results := &scope.FindScopeDashboardBindingsResults{
|
||||
Message: fmt.Sprintf("Find: %s", scopes),
|
||||
Items: make([]scope.ScopeDashboardBinding, 0),
|
||||
}
|
||||
|
||||
// we can improve the performance by calling .List once per scope if they are index by labels.
|
||||
// The API stays the same thou.
|
||||
for _, item := range all.Items {
|
||||
for _, s := range scopes {
|
||||
if item.Spec.Scope == s {
|
||||
results.Items = append(results.Items, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sort the dashboard lists based on dashboard title.
|
||||
slices.SortFunc(results.Items, func(i, j scope.ScopeDashboardBinding) int {
|
||||
return strings.Compare(i.Status.DashboardTitle, j.Status.DashboardTitle)
|
||||
})
|
||||
|
||||
logger.FromContext(req.Context()).Debug("find scopedashboardbinding", "raw", len(all.Items), "filtered", len(results.Items), "scopeQueryParams", strings.Join(scopes, ","))
|
||||
|
||||
responder.Object(200, results)
|
||||
}), nil
|
||||
}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
package scope
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
scope "github.com/grafana/grafana/pkg/apis/scope/v0alpha1"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestFilterAndAppendItem(t *testing.T) {
|
||||
tcs := []struct {
|
||||
Description string
|
||||
|
||||
ParentName string
|
||||
Title string
|
||||
|
||||
QueryParam string
|
||||
ParentParam string
|
||||
|
||||
ExpectedMatches int
|
||||
}{
|
||||
{
|
||||
Description: "Matching parent without query param",
|
||||
ParentName: "ParentNumberOne",
|
||||
Title: "item",
|
||||
QueryParam: "",
|
||||
ParentParam: "ParentNumberOne",
|
||||
ExpectedMatches: 1,
|
||||
},
|
||||
{
|
||||
Description: "Not matching parent",
|
||||
ParentName: "ParentNumberOne",
|
||||
Title: "itemOne",
|
||||
QueryParam: "itemTwo",
|
||||
ParentParam: "ParentNumberTwo",
|
||||
ExpectedMatches: 0,
|
||||
},
|
||||
{
|
||||
Description: "Matching parent and query param",
|
||||
ParentName: "ParentNumberOne",
|
||||
Title: "itemOne",
|
||||
QueryParam: "itemOne",
|
||||
ParentParam: "ParentNumberOne",
|
||||
ExpectedMatches: 1,
|
||||
},
|
||||
{
|
||||
Description: "matching parent but not matching query param",
|
||||
ParentName: "ParentNumberOne",
|
||||
Title: "itemOne",
|
||||
QueryParam: "itemTwo",
|
||||
ParentParam: "ParentNumberOne",
|
||||
ExpectedMatches: 0,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tcs {
|
||||
results := &scope.FindScopeNodeChildrenResults{}
|
||||
item := scope.ScopeNode{
|
||||
Spec: scope.ScopeNodeSpec{
|
||||
ParentName: tc.ParentName,
|
||||
Title: tc.Title,
|
||||
Description: "item description",
|
||||
NodeType: "item type",
|
||||
LinkType: "item link type",
|
||||
LinkID: "item link ID",
|
||||
},
|
||||
}
|
||||
filterAndAppendItem(item, tc.ParentParam, tc.QueryParam, results)
|
||||
require.Equal(t, len(results.Items), tc.ExpectedMatches, tc.Description)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,224 +0,0 @@
|
|||
package scope
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||
"k8s.io/kube-openapi/pkg/common"
|
||||
"k8s.io/kube-openapi/pkg/spec3"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
|
||||
scope "github.com/grafana/grafana/pkg/apis/scope/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/services/apiserver/builder"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
)
|
||||
|
||||
var _ builder.APIGroupBuilder = (*ScopeAPIBuilder)(nil)
|
||||
|
||||
// This is used just so wire has something unique to return
|
||||
type ScopeAPIBuilder struct{}
|
||||
|
||||
func NewScopeAPIBuilder() *ScopeAPIBuilder {
|
||||
return &ScopeAPIBuilder{}
|
||||
}
|
||||
|
||||
func RegisterAPIService(features featuremgmt.FeatureToggles, apiregistration builder.APIRegistrar, reg prometheus.Registerer) *ScopeAPIBuilder {
|
||||
if !featuremgmt.AnyEnabled(features,
|
||||
featuremgmt.FlagScopeApi,
|
||||
featuremgmt.FlagGrafanaAPIServerWithExperimentalAPIs) {
|
||||
return nil // skip registration unless opting into experimental apis
|
||||
}
|
||||
builder := NewScopeAPIBuilder()
|
||||
apiregistration.RegisterAPI(builder)
|
||||
return builder
|
||||
}
|
||||
|
||||
func (b *ScopeAPIBuilder) GetAuthorizer() authorizer.Authorizer {
|
||||
return nil // default authorizer is fine
|
||||
}
|
||||
|
||||
func (b *ScopeAPIBuilder) GetGroupVersion() schema.GroupVersion {
|
||||
return scope.SchemeGroupVersion
|
||||
}
|
||||
|
||||
func (b *ScopeAPIBuilder) InstallSchema(scheme *runtime.Scheme) error {
|
||||
err := scope.AddToScheme(scheme)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = scheme.AddFieldLabelConversionFunc(
|
||||
scope.ScopeResourceInfo.GroupVersionKind(),
|
||||
func(label, value string) (string, string, error) {
|
||||
fieldSet := SelectableScopeFields(&scope.Scope{})
|
||||
for key := range fieldSet {
|
||||
if label == key {
|
||||
return label, value, nil
|
||||
}
|
||||
}
|
||||
return "", "", fmt.Errorf("field label not supported for %s: %s", scope.ScopeResourceInfo.GroupVersionKind(), label)
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = scheme.AddFieldLabelConversionFunc(
|
||||
scope.ScopeDashboardBindingResourceInfo.GroupVersionKind(),
|
||||
func(label, value string) (string, string, error) {
|
||||
fieldSet := SelectableScopeDashboardBindingFields(&scope.ScopeDashboardBinding{})
|
||||
for key := range fieldSet {
|
||||
if label == key {
|
||||
return label, value, nil
|
||||
}
|
||||
}
|
||||
return "", "", fmt.Errorf("field label not supported for %s: %s", scope.ScopeDashboardBindingResourceInfo.GroupVersionKind(), label)
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = scheme.AddFieldLabelConversionFunc(
|
||||
scope.ScopeNodeResourceInfo.GroupVersionKind(),
|
||||
func(label, value string) (string, string, error) {
|
||||
fieldSet := SelectableScopeNodeFields(&scope.ScopeNode{})
|
||||
for key := range fieldSet {
|
||||
if label == key {
|
||||
return label, value, nil
|
||||
}
|
||||
}
|
||||
return "", "", fmt.Errorf("field label not supported for %s: %s", scope.ScopeNodeResourceInfo.GroupVersionKind(), label)
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// This is required for --server-side apply
|
||||
err = scope.AddKnownTypes(scope.InternalGroupVersion, scheme)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Only one version right now
|
||||
return scheme.SetVersionPriority(scope.SchemeGroupVersion)
|
||||
}
|
||||
|
||||
func (b *ScopeAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.APIGroupInfo, opts builder.APIGroupOptions) error {
|
||||
scheme := opts.Scheme
|
||||
optsGetter := opts.OptsGetter
|
||||
|
||||
scopeResourceInfo := scope.ScopeResourceInfo
|
||||
scopeDashboardResourceInfo := scope.ScopeDashboardBindingResourceInfo
|
||||
scopeNodeResourceInfo := scope.ScopeNodeResourceInfo
|
||||
|
||||
storage := map[string]rest.Storage{}
|
||||
|
||||
scopeStorage, err := newScopeStorage(scheme, optsGetter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
storage[scopeResourceInfo.StoragePath()] = scopeStorage
|
||||
|
||||
scopeDashboardStorage, scopedDashboardStatusStorage, err := newScopeDashboardBindingStorage(scheme, optsGetter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
storage[scopeDashboardResourceInfo.StoragePath()] = scopeDashboardStorage
|
||||
storage[scopeDashboardResourceInfo.StoragePath()+"/status"] = scopedDashboardStatusStorage
|
||||
|
||||
scopeNodeStorage, err := newScopeNodeStorage(scheme, optsGetter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
storage[scopeNodeResourceInfo.StoragePath()] = scopeNodeStorage
|
||||
|
||||
// Adds a rest.Connector
|
||||
// NOTE! the server has a hardcoded rewrite filter that fills in a name
|
||||
// so the standard k8s plumbing continues to work
|
||||
storage["scope_node_children"] = &findREST{scopeNodeStorage: scopeNodeStorage}
|
||||
|
||||
// Adds a rest.Connector
|
||||
// NOTE! the server has a hardcoded rewrite filter that fills in a name
|
||||
// so the standard k8s plumbing continues to work
|
||||
storage["scope_dashboard_bindings"] = &findScopeDashboardsREST{scopeDashboardStorage: scopeDashboardStorage}
|
||||
|
||||
apiGroupInfo.VersionedResourcesStorageMap[scope.VERSION] = storage
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *ScopeAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions {
|
||||
return scope.GetOpenAPIDefinitions
|
||||
}
|
||||
|
||||
func (b *ScopeAPIBuilder) PostProcessOpenAPI(oas *spec3.OpenAPI) (*spec3.OpenAPI, error) {
|
||||
// The plugin description
|
||||
oas.Info.Description = "Grafana scopes"
|
||||
|
||||
// The root api URL
|
||||
root := "/apis/" + b.GetGroupVersion().String() + "/"
|
||||
|
||||
// Add query parameters to the rest.Connector
|
||||
sub := oas.Paths.Paths[root+"namespaces/{namespace}/scope_node_children/{name}"]
|
||||
if sub != nil && sub.Get != nil {
|
||||
sub.Parameters = []*spec3.Parameter{
|
||||
{
|
||||
ParameterProps: spec3.ParameterProps{
|
||||
Name: "namespace",
|
||||
In: "path",
|
||||
Description: "object name and auth scope, such as for teams and projects",
|
||||
Example: "default",
|
||||
Required: true,
|
||||
Schema: spec.StringProperty().UniqueValues(),
|
||||
},
|
||||
},
|
||||
}
|
||||
sub.Get.Description = "Navigate the scopes tree"
|
||||
sub.Get.Parameters = []*spec3.Parameter{
|
||||
{
|
||||
ParameterProps: spec3.ParameterProps{
|
||||
Name: "parent",
|
||||
In: "query",
|
||||
Description: "The parent scope node",
|
||||
},
|
||||
},
|
||||
}
|
||||
delete(oas.Paths.Paths, root+"namespaces/{namespace}/scope_node_children/{name}")
|
||||
oas.Paths.Paths[root+"namespaces/{namespace}/find/scope_node_children"] = sub
|
||||
}
|
||||
|
||||
findDashboardPath := oas.Paths.Paths[root+"namespaces/{namespace}/scope_dashboard_bindings/{name}"]
|
||||
if findDashboardPath != nil && sub.Get != nil {
|
||||
sub.Parameters = []*spec3.Parameter{
|
||||
{
|
||||
ParameterProps: spec3.ParameterProps{
|
||||
Name: "namespace",
|
||||
In: "path",
|
||||
Description: "object name and auth scope, such as for teams and projects",
|
||||
Example: "default",
|
||||
Required: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
findDashboardPath.Get.Description = "find scope dashboard bindings that match any of the given scopes."
|
||||
findDashboardPath.Get.Parameters = []*spec3.Parameter{
|
||||
{
|
||||
ParameterProps: spec3.ParameterProps{
|
||||
Name: "scope",
|
||||
In: "query",
|
||||
Description: "A scope name (id) to match against, this parameter may be repeated",
|
||||
},
|
||||
},
|
||||
}
|
||||
delete(oas.Paths.Paths, root+"namespaces/{namespace}/scope_dashboard_bindings/{name}")
|
||||
oas.Paths.Paths[root+"namespaces/{namespace}/find/scope_dashboard_bindings"] = findDashboardPath
|
||||
}
|
||||
|
||||
return oas, nil
|
||||
}
|
||||
|
|
@ -1,142 +0,0 @@
|
|||
package scope
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apiserver/pkg/registry/generic"
|
||||
genericregistry "k8s.io/apiserver/pkg/registry/generic/registry"
|
||||
apistore "k8s.io/apiserver/pkg/storage"
|
||||
|
||||
scope "github.com/grafana/grafana/pkg/apis/scope/v0alpha1"
|
||||
grafanaregistry "github.com/grafana/grafana/pkg/apiserver/registry/generic"
|
||||
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
|
||||
)
|
||||
|
||||
var _ grafanarest.Storage = (*storage)(nil)
|
||||
|
||||
type storage struct {
|
||||
*genericregistry.Store
|
||||
}
|
||||
|
||||
func newScopeStorage(scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter) (*storage, error) {
|
||||
resourceInfo := scope.ScopeResourceInfo
|
||||
strategy := grafanaregistry.NewStrategy(scheme, resourceInfo.GroupVersion())
|
||||
store := &genericregistry.Store{
|
||||
NewFunc: resourceInfo.NewFunc,
|
||||
NewListFunc: resourceInfo.NewListFunc,
|
||||
KeyRootFunc: grafanaregistry.KeyRootFunc(resourceInfo.GroupResource()),
|
||||
KeyFunc: grafanaregistry.NamespaceKeyFunc(resourceInfo.GroupResource()),
|
||||
PredicateFunc: Matcher,
|
||||
DefaultQualifiedResource: resourceInfo.GroupResource(),
|
||||
SingularQualifiedResource: resourceInfo.SingularGroupResource(),
|
||||
TableConvertor: resourceInfo.TableConverter(),
|
||||
CreateStrategy: strategy,
|
||||
UpdateStrategy: strategy,
|
||||
DeleteStrategy: strategy,
|
||||
}
|
||||
options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: GetAttrs}
|
||||
if err := store.CompleteWithOptions(options); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &storage{Store: store}, nil
|
||||
}
|
||||
|
||||
func newScopeDashboardBindingStorage(scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter) (*storage, *grafanaregistry.StatusREST, error) {
|
||||
resourceInfo := scope.ScopeDashboardBindingResourceInfo
|
||||
strategy := grafanaregistry.NewStrategy(scheme, resourceInfo.GroupVersion())
|
||||
|
||||
store := &genericregistry.Store{
|
||||
NewFunc: resourceInfo.NewFunc,
|
||||
NewListFunc: resourceInfo.NewListFunc,
|
||||
KeyRootFunc: grafanaregistry.KeyRootFunc(resourceInfo.GroupResource()),
|
||||
KeyFunc: grafanaregistry.NamespaceKeyFunc(resourceInfo.GroupResource()),
|
||||
PredicateFunc: Matcher,
|
||||
DefaultQualifiedResource: resourceInfo.GroupResource(),
|
||||
SingularQualifiedResource: resourceInfo.SingularGroupResource(),
|
||||
TableConvertor: resourceInfo.TableConverter(),
|
||||
CreateStrategy: strategy,
|
||||
UpdateStrategy: strategy,
|
||||
DeleteStrategy: strategy,
|
||||
}
|
||||
options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: GetAttrs}
|
||||
if err := store.CompleteWithOptions(options); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
statusStrategy := grafanaregistry.NewStatusStrategy(scheme, resourceInfo.GroupVersion())
|
||||
statusREST := grafanaregistry.NewStatusREST(store, statusStrategy)
|
||||
return &storage{Store: store}, statusREST, nil
|
||||
}
|
||||
|
||||
func newScopeNodeStorage(scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter) (*storage, error) {
|
||||
resourceInfo := scope.ScopeNodeResourceInfo
|
||||
strategy := grafanaregistry.NewStrategy(scheme, resourceInfo.GroupVersion())
|
||||
|
||||
store := &genericregistry.Store{
|
||||
NewFunc: resourceInfo.NewFunc,
|
||||
NewListFunc: resourceInfo.NewListFunc,
|
||||
KeyRootFunc: grafanaregistry.KeyRootFunc(resourceInfo.GroupResource()),
|
||||
KeyFunc: grafanaregistry.NamespaceKeyFunc(resourceInfo.GroupResource()),
|
||||
PredicateFunc: Matcher,
|
||||
DefaultQualifiedResource: resourceInfo.GroupResource(),
|
||||
SingularQualifiedResource: resourceInfo.SingularGroupResource(),
|
||||
TableConvertor: resourceInfo.TableConverter(),
|
||||
CreateStrategy: strategy,
|
||||
UpdateStrategy: strategy,
|
||||
DeleteStrategy: strategy,
|
||||
}
|
||||
options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: GetAttrs}
|
||||
if err := store.CompleteWithOptions(options); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &storage{Store: store}, nil
|
||||
}
|
||||
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
if s, ok := obj.(*scope.Scope); ok {
|
||||
return labels.Set(s.Labels), SelectableScopeFields(s), nil
|
||||
}
|
||||
if s, ok := obj.(*scope.ScopeDashboardBinding); ok {
|
||||
return labels.Set(s.Labels), SelectableScopeDashboardBindingFields(s), nil
|
||||
}
|
||||
if s, ok := obj.(*scope.ScopeNode); ok {
|
||||
return labels.Set(s.Labels), SelectableScopeNodeFields(s), nil
|
||||
}
|
||||
return nil, nil, fmt.Errorf("not a scope or ScopeDashboardBinding object")
|
||||
}
|
||||
|
||||
// Matcher returns a generic.SelectionPredicate that matches on label and field selectors.
|
||||
func Matcher(label labels.Selector, field fields.Selector) apistore.SelectionPredicate {
|
||||
return apistore.SelectionPredicate{
|
||||
Label: label,
|
||||
Field: field,
|
||||
GetAttrs: GetAttrs,
|
||||
}
|
||||
}
|
||||
|
||||
func SelectableScopeFields(obj *scope.Scope) fields.Set {
|
||||
return generic.MergeFieldsSets(generic.ObjectMetaFieldsSet(&obj.ObjectMeta, false), fields.Set{
|
||||
"spec.title": obj.Spec.Title,
|
||||
})
|
||||
}
|
||||
|
||||
func SelectableScopeDashboardBindingFields(obj *scope.ScopeDashboardBinding) fields.Set {
|
||||
return generic.MergeFieldsSets(generic.ObjectMetaFieldsSet(&obj.ObjectMeta, false), fields.Set{
|
||||
"spec.scope": obj.Spec.Scope,
|
||||
})
|
||||
}
|
||||
|
||||
func SelectableScopeNodeFields(obj *scope.ScopeNode) fields.Set {
|
||||
parentName := ""
|
||||
|
||||
if obj != nil {
|
||||
parentName = obj.Spec.ParentName
|
||||
}
|
||||
|
||||
return generic.MergeFieldsSets(generic.ObjectMetaFieldsSet(&obj.ObjectMeta, false), fields.Set{
|
||||
"spec.parentName": parentName,
|
||||
})
|
||||
}
|
||||
|
|
@ -15,7 +15,6 @@ import (
|
|||
"github.com/grafana/grafana/pkg/registry/apis/iam"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/provisioning"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/query"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/scope"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/service"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/userstorage"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/plugincontext"
|
||||
|
|
@ -42,7 +41,6 @@ var WireSet = wire.NewSet(
|
|||
provisioning.RegisterAPIService,
|
||||
service.RegisterAPIService,
|
||||
query.RegisterAPIService,
|
||||
scope.RegisterAPIService,
|
||||
notifications.RegisterAPIService,
|
||||
userstorage.RegisterAPIService,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,84 +0,0 @@
|
|||
package scopes
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/tests/apis"
|
||||
"github.com/grafana/grafana/pkg/tests/testinfra"
|
||||
"github.com/stretchr/testify/require"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
func TestIntegrationScopeNodesExample(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping integration test in short mode.")
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
helper := apis.NewK8sTestHelper(t, testinfra.GrafanaOpts{
|
||||
AppModeProduction: false, // required for experimental APIs
|
||||
EnableFeatureToggles: []string{
|
||||
featuremgmt.FlagGrafanaAPIServerWithExperimentalAPIs, // Required to start the example service
|
||||
},
|
||||
})
|
||||
|
||||
scopeClient := helper.GetResourceClient(apis.ResourceClientArgs{
|
||||
User: helper.Org1.Admin,
|
||||
Namespace: "default", // actually org1
|
||||
GVR: schema.GroupVersionResource{
|
||||
Group: "scope.grafana.app", Version: "v0alpha1", Resource: "scopes",
|
||||
},
|
||||
})
|
||||
|
||||
scopeNodesClient := helper.GetResourceClient(apis.ResourceClientArgs{
|
||||
User: helper.Org1.Admin,
|
||||
Namespace: "default", // actually org1
|
||||
GVR: schema.GroupVersionResource{
|
||||
Group: "scope.grafana.app", Version: "v0alpha1", Resource: "scopenodes",
|
||||
},
|
||||
})
|
||||
|
||||
createOptions := metav1.CreateOptions{FieldValidation: "Strict"}
|
||||
|
||||
t.Run("Create scopes", func(t *testing.T) {
|
||||
ul := jsonListToUnstructuredList(t, "testdata/scopeNodesExample/scopes.json")
|
||||
|
||||
for _, item := range ul.Items {
|
||||
_, err := scopeClient.Resource.Create(ctx, &item, createOptions)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
found, err := scopeClient.Resource.List(ctx, metav1.ListOptions{})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, found.Items, 5)
|
||||
})
|
||||
|
||||
t.Run("Create scopeNodes", func(t *testing.T) {
|
||||
ul := jsonListToUnstructuredList(t, "testdata/scopeNodesExample/scopeNodes.json")
|
||||
|
||||
for _, item := range ul.Items {
|
||||
_, err := scopeNodesClient.Resource.Create(ctx, &item, createOptions)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
found, err := scopeNodesClient.Resource.List(ctx, metav1.ListOptions{})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, found.Items, 12)
|
||||
})
|
||||
}
|
||||
|
||||
func jsonListToUnstructuredList(t *testing.T, fname string) (ul unstructured.UnstructuredList) {
|
||||
// nolint:gosec
|
||||
f, err := os.ReadFile(fname)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = json.Unmarshal(f, &ul)
|
||||
require.NoError(t, err)
|
||||
return
|
||||
}
|
||||
|
|
@ -1,221 +0,0 @@
|
|||
package scopes
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/tests/apis"
|
||||
"github.com/grafana/grafana/pkg/tests/testinfra"
|
||||
"github.com/grafana/grafana/pkg/tests/testsuite"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
testsuite.Run(m)
|
||||
}
|
||||
|
||||
func TestIntegrationScopes(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping integration test")
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
helper := apis.NewK8sTestHelper(t, testinfra.GrafanaOpts{
|
||||
AppModeProduction: true,
|
||||
EnableFeatureToggles: []string{
|
||||
featuremgmt.FlagScopeApi, // Required to register the API
|
||||
},
|
||||
})
|
||||
|
||||
t.Run("Check discovery client", func(t *testing.T) {
|
||||
disco := helper.NewDiscoveryClient()
|
||||
resources, err := disco.ServerResourcesForGroupVersion("scope.grafana.app/v0alpha1")
|
||||
require.NoError(t, err)
|
||||
|
||||
v1Disco, err := json.MarshalIndent(resources, "", " ")
|
||||
require.NoError(t, err)
|
||||
//fmt.Printf("%s", string(v1Disco))
|
||||
|
||||
require.JSONEq(t, `{
|
||||
"kind": "APIResourceList",
|
||||
"apiVersion": "v1",
|
||||
"groupVersion": "scope.grafana.app/v0alpha1",
|
||||
"resources": [
|
||||
{
|
||||
"name": "scope_dashboard_bindings",
|
||||
"singularName": "FindScopeDashboardsResult",
|
||||
"namespaced": true,
|
||||
"kind": "FindScopeDashboardBindingsResults",
|
||||
"verbs": [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "scope_node_children",
|
||||
"singularName": "FindScopeNodeChildrenResults",
|
||||
"namespaced": true,
|
||||
"kind": "FindScopeNodeChildrenResults",
|
||||
"verbs": [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "scopedashboardbindings",
|
||||
"singularName": "scopedashboardbinding",
|
||||
"namespaced": true,
|
||||
"kind": "ScopeDashboardBinding",
|
||||
"verbs": [
|
||||
"create",
|
||||
"delete",
|
||||
"deletecollection",
|
||||
"get",
|
||||
"list",
|
||||
"patch",
|
||||
"update",
|
||||
"watch"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "scopedashboardbindings/status",
|
||||
"singularName": "",
|
||||
"namespaced": true,
|
||||
"kind": "ScopeDashboardBinding",
|
||||
"verbs": [
|
||||
"get",
|
||||
"patch",
|
||||
"update"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "scopenodes",
|
||||
"singularName": "scopenode",
|
||||
"namespaced": true,
|
||||
"kind": "ScopeNode",
|
||||
"verbs": [
|
||||
"create",
|
||||
"delete",
|
||||
"deletecollection",
|
||||
"get",
|
||||
"list",
|
||||
"patch",
|
||||
"update",
|
||||
"watch"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "scopes",
|
||||
"singularName": "scope",
|
||||
"namespaced": true,
|
||||
"kind": "Scope",
|
||||
"verbs": [
|
||||
"create",
|
||||
"delete",
|
||||
"deletecollection",
|
||||
"get",
|
||||
"list",
|
||||
"patch",
|
||||
"update",
|
||||
"watch"
|
||||
]
|
||||
}
|
||||
]
|
||||
}`, string(v1Disco))
|
||||
})
|
||||
|
||||
t.Run("Check create and list", func(t *testing.T) {
|
||||
// Scope create+get
|
||||
scopeClient := helper.GetResourceClient(apis.ResourceClientArgs{
|
||||
User: helper.Org1.Admin,
|
||||
Namespace: "default", // actually org1
|
||||
GVR: schema.GroupVersionResource{
|
||||
Group: "scope.grafana.app", Version: "v0alpha1", Resource: "scopes",
|
||||
},
|
||||
})
|
||||
createOptions := metav1.CreateOptions{FieldValidation: "Strict"}
|
||||
|
||||
s0, err := scopeClient.Resource.Create(ctx,
|
||||
helper.LoadYAMLOrJSONFile("testdata/example-scope.yaml"),
|
||||
createOptions,
|
||||
)
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "example", s0.GetName())
|
||||
s1, err := scopeClient.Resource.Get(ctx, "example", metav1.GetOptions{})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t,
|
||||
mustNestedString(s0.Object, "spec", "title"),
|
||||
mustNestedString(s1.Object, "spec", "title"),
|
||||
)
|
||||
|
||||
_, err = scopeClient.Resource.Create(ctx,
|
||||
helper.LoadYAMLOrJSONFile("testdata/example-scope2.yaml"),
|
||||
createOptions,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Name length test
|
||||
scope3 := helper.LoadYAMLOrJSONFile("testdata/example-scope3.yaml")
|
||||
|
||||
// Name too long (>253)
|
||||
scope3.SetName(strings.Repeat("0", 254))
|
||||
_, err = scopeClient.Resource.Create(ctx,
|
||||
scope3,
|
||||
createOptions,
|
||||
)
|
||||
require.Error(t, err)
|
||||
|
||||
// Maximum allowed length for name (253)
|
||||
scope3.SetName(strings.Repeat("0", 253))
|
||||
_, err = scopeClient.Resource.Create(ctx,
|
||||
scope3,
|
||||
createOptions,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Field Selector test
|
||||
found, err := scopeClient.Resource.List(ctx, metav1.ListOptions{
|
||||
FieldSelector: "spec.title=foo-scope",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, found.Items, 1)
|
||||
require.Equal(t,
|
||||
"example2",
|
||||
mustNestedString(found.Items[0].Object, "metadata", "name"),
|
||||
)
|
||||
|
||||
// Create bindings
|
||||
scopeDashboardBindingClient := helper.GetResourceClient(apis.ResourceClientArgs{
|
||||
User: helper.Org1.Admin,
|
||||
Namespace: "default", // actually org1
|
||||
GVR: schema.GroupVersionResource{
|
||||
Group: "scope.grafana.app", Version: "v0alpha1", Resource: "scopedashboardbindings",
|
||||
},
|
||||
})
|
||||
_, err = scopeDashboardBindingClient.Resource.Create(ctx,
|
||||
helper.LoadYAMLOrJSONFile("testdata/example-scope-dashboard-binding-abc.yaml"),
|
||||
createOptions,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
_, err = scopeDashboardBindingClient.Resource.Create(ctx,
|
||||
helper.LoadYAMLOrJSONFile("testdata/example-scope-dashboard-binding-xyz.yaml"),
|
||||
createOptions,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
found, err = scopeDashboardBindingClient.Resource.List(ctx, metav1.ListOptions{})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, found.Items, 2)
|
||||
})
|
||||
}
|
||||
|
||||
func mustNestedString(obj map[string]interface{}, fields ...string) string {
|
||||
v, _, _ := unstructured.NestedString(obj, fields...)
|
||||
return v
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
apiVersion: scope.grafana.app/v0alpha1
|
||||
kind: ScopeDashboardBinding
|
||||
metadata:
|
||||
name: example_abc
|
||||
spec:
|
||||
scope: example
|
||||
dashboard: abc
|
||||
status:
|
||||
dashboardTitle: "Example Dashboard ABC"
|
||||
groups: ["group1", "group2"]
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
apiVersion: scope.grafana.app/v0alpha1
|
||||
kind: ScopeDashboardBinding
|
||||
metadata:
|
||||
name: example_xyz
|
||||
spec:
|
||||
scope: example
|
||||
dashboard: xyz
|
||||
status:
|
||||
dashboardTitle: "Example Dashboard XYZ"
|
||||
groups: ["group2", "group3"]
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
apiVersion: scope.grafana.app/v0alpha1
|
||||
kind: Scope
|
||||
metadata:
|
||||
name: example
|
||||
spec:
|
||||
title: bar-scope
|
||||
description: Longer description for a scope
|
||||
filters:
|
||||
- key: aaa
|
||||
operator: equals
|
||||
value: bbb
|
||||
- key: ccc
|
||||
operator: not-equals
|
||||
value: ddd
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
apiVersion: scope.grafana.app/v0alpha1
|
||||
kind: Scope
|
||||
metadata:
|
||||
name: example2
|
||||
spec:
|
||||
title: foo-scope
|
||||
description: Longer description for a scope
|
||||
filters:
|
||||
- key: aaa
|
||||
operator: equals
|
||||
value: zzz
|
||||
- key: ccc
|
||||
operator: not-equals
|
||||
value: yyy
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
apiVersion: scope.grafana.app/v0alpha1
|
||||
kind: Scope
|
||||
metadata:
|
||||
name: example-long
|
||||
spec:
|
||||
title: baz-scope
|
||||
description: Longer description for a scope
|
||||
filters:
|
||||
- key: aaa
|
||||
operator: equals
|
||||
value: eee
|
||||
- key: ccc
|
||||
operator: not-equals
|
||||
value: fff
|
||||
|
|
@ -1,179 +0,0 @@
|
|||
{
|
||||
"kind": "List",
|
||||
"items": [
|
||||
{
|
||||
"apiVersion": "scope.grafana.app/v0alpha1",
|
||||
"kind": "ScopeNode",
|
||||
"metadata": {
|
||||
"name": "applications"
|
||||
},
|
||||
"spec": {
|
||||
"description": "Application Scopes",
|
||||
"title": "Applications",
|
||||
"nodeType": "container"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "scope.grafana.app/v0alpha1",
|
||||
"kind": "ScopeNode",
|
||||
"metadata": {
|
||||
"name": "applications-clusters"
|
||||
},
|
||||
"spec": {
|
||||
"description": "Application/Clusters Scopes",
|
||||
"title": "Clusters",
|
||||
"nodeType": "container",
|
||||
"parentName": "applications",
|
||||
"linkId": "indexHelperCluster",
|
||||
"linkType": "scope"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "scope.grafana.app/v0alpha1",
|
||||
"kind": "ScopeNode",
|
||||
"metadata": {
|
||||
"name": "clusters"
|
||||
},
|
||||
"spec": {
|
||||
"description": "Cluster Scopes",
|
||||
"title": "Clusters",
|
||||
"nodeType": "container",
|
||||
"linkId": "indexHelperCluster",
|
||||
"linkType": "scope"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "scope.grafana.app/v0alpha1",
|
||||
"kind": "ScopeNode",
|
||||
"metadata": {
|
||||
"name": "clusters-application"
|
||||
},
|
||||
"spec": {
|
||||
"description": "Clusters/Application Scopes",
|
||||
"title": "Applications",
|
||||
"nodeType": "container",
|
||||
"parentName": "clusters"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "scope.grafana.app/v0alpha1",
|
||||
"kind": "ScopeNode",
|
||||
"metadata": {
|
||||
"name": "applications-slothPictureFactory"
|
||||
},
|
||||
"spec": {
|
||||
"description": "slothPictureFactory",
|
||||
"title": "slothPictureFactory",
|
||||
"nodeType": "leaf",
|
||||
"parentName": "applications",
|
||||
"linkId": "slothPictureFactory",
|
||||
"linkType": "scope"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "scope.grafana.app/v0alpha1",
|
||||
"kind": "ScopeNode",
|
||||
"metadata": {
|
||||
"name": "applications-slothVoteTracker"
|
||||
},
|
||||
"spec": {
|
||||
"description": "slothVoteTracker",
|
||||
"title": "slothVoteTracker",
|
||||
"nodeType": "leaf",
|
||||
"parentName": "applications",
|
||||
"linkId": "slothVoteTracker",
|
||||
"linkType": "scope"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "scope.grafana.app/v0alpha1",
|
||||
"kind": "ScopeNode",
|
||||
"metadata": {
|
||||
"name": "applications-clusters-slothClusterNorth"
|
||||
},
|
||||
"spec": {
|
||||
"description": "slothClusterNorth",
|
||||
"title": "slothClusterNorth",
|
||||
"nodeType": "leaf",
|
||||
"parentName": "applications-clusters",
|
||||
"linkId": "slothClusterNorth",
|
||||
"linkType": "scope"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "scope.grafana.app/v0alpha1",
|
||||
"kind": "ScopeNode",
|
||||
"metadata": {
|
||||
"name": "applications-clusters-slothClusterSouth"
|
||||
},
|
||||
"spec": {
|
||||
"description": "slothClusterSouth",
|
||||
"title": "slothClusterSouth",
|
||||
"nodeType": "leaf",
|
||||
"parentName": "applications-clusters",
|
||||
"linkId": "slothClusterSouth",
|
||||
"linkType": "scope"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "scope.grafana.app/v0alpha1",
|
||||
"kind": "ScopeNode",
|
||||
"metadata": {
|
||||
"name": "clusters-slothClusterNorth"
|
||||
},
|
||||
"spec": {
|
||||
"description": "slothClusterNorth",
|
||||
"title": "slothClusterNorth",
|
||||
"nodeType": "leaf",
|
||||
"parentName": "clusters",
|
||||
"linkId": "slothClusterNorth",
|
||||
"linkType": "scope"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "scope.grafana.app/v0alpha1",
|
||||
"kind": "ScopeNode",
|
||||
"metadata": {
|
||||
"name": "clusters-slothClusterSouth"
|
||||
},
|
||||
"spec": {
|
||||
"description": "slothClusterSouth",
|
||||
"title": "slothClusterSouth",
|
||||
"nodeType": "leaf",
|
||||
"parentName": "clusters",
|
||||
"linkId": "slothClusterSouth",
|
||||
"linkType": "scope"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "scope.grafana.app/v0alpha1",
|
||||
"kind": "ScopeNode",
|
||||
"metadata": {
|
||||
"name": "clusters-applications-slothPictureFactory"
|
||||
},
|
||||
"spec": {
|
||||
"description": "slothPictureFactory",
|
||||
"title": "slothPictureFactory",
|
||||
"nodeType": "leaf",
|
||||
"parentName": "clusters-applications",
|
||||
"linkId": "slothPictureFactory",
|
||||
"linkType": "scope"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "scope.grafana.app/v0alpha1",
|
||||
"kind": "ScopeNode",
|
||||
"metadata": {
|
||||
"name": "clusters-applications-slothVoteTracker"
|
||||
},
|
||||
"spec": {
|
||||
"description": "slothVoteTracker",
|
||||
"title": "slothVoteTracker",
|
||||
"nodeType": "leaf",
|
||||
"parentName": "clusters-applications",
|
||||
"linkId": "slothVoteTracker",
|
||||
"linkType": "scope"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,95 +0,0 @@
|
|||
{
|
||||
"kind": "List",
|
||||
"items": [
|
||||
{
|
||||
"apiVersion": "scope.grafana.app/v0alpha1",
|
||||
"kind": "Scope",
|
||||
"metadata": {
|
||||
"name": "slothClusterNorth"
|
||||
},
|
||||
"spec": {
|
||||
"description": "slothClusterNorth",
|
||||
"filters": [
|
||||
{
|
||||
"key": "cluster",
|
||||
"operator": "equals",
|
||||
"value": "slothClusterNorth"
|
||||
}
|
||||
],
|
||||
"title": "slothClusterNorth"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "scope.grafana.app/v0alpha1",
|
||||
"kind": "Scope",
|
||||
"metadata": {
|
||||
"name": "slothClusterSouth"
|
||||
},
|
||||
"spec": {
|
||||
"description": "slothClusterSouth",
|
||||
"filters": [
|
||||
{
|
||||
"key": "cluster",
|
||||
"operator": "equals",
|
||||
"value": "slothClusterSouth"
|
||||
}
|
||||
],
|
||||
"title": "slothClusterSouth"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "scope.grafana.app/v0alpha1",
|
||||
"kind": "Scope",
|
||||
"metadata": {
|
||||
"name": "slothPictureFactory"
|
||||
},
|
||||
"spec": {
|
||||
"description": "slothPictureFactory",
|
||||
"filters": [
|
||||
{
|
||||
"key": "app",
|
||||
"operator": "equals",
|
||||
"value": "slothPictureFactory"
|
||||
}
|
||||
],
|
||||
"title": "slothPictureFactory"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "scope.grafana.app/v0alpha1",
|
||||
"kind": "Scope",
|
||||
"metadata": {
|
||||
"name": "slothVoteTracker"
|
||||
},
|
||||
"spec": {
|
||||
"description": "slothVoteTracker",
|
||||
"filters": [
|
||||
{
|
||||
"key": "app",
|
||||
"operator": "equals",
|
||||
"value": "slothVoteTracker"
|
||||
}
|
||||
],
|
||||
"title": "slothVoteTracker"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "scope.grafana.app/v0alpha1",
|
||||
"kind": "Scope",
|
||||
"metadata": {
|
||||
"name": "indexHelperCluster"
|
||||
},
|
||||
"spec": {
|
||||
"description": "redundant label filter but makes queries faster",
|
||||
"filters": [
|
||||
{
|
||||
"key": "indexHelper",
|
||||
"operator": "equals",
|
||||
"value": "cluster"
|
||||
}
|
||||
],
|
||||
"title": "Cluster Index Helper"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Reference in New Issue