mirror of https://github.com/grafana/grafana
scopes: moves scopes to enterprise (#100746)
Signed-off-by: bergquist <carl.bergquist@gmail.com>macabu/go-modernize
parent
0290da6aaa
commit
79c0e5e3ec
@ -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 |
||||
} |
@ -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 |
@ -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, |
||||
}) |
||||
} |
@ -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