Scopes: Name relationship objects *binding (#84955)

Signed-off-by: bergquist <carl.bergquist@gmail.com>
Co-authored-by: Bogdan Matei <bogdan.matei@grafana.com>
This commit is contained in:
Carl Bergquist 2024-03-26 15:52:12 +01:00 committed by GitHub
parent c39b9b2cbe
commit b214b07695
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 84 additions and 69 deletions

View File

@ -162,7 +162,7 @@ func schema_pkg_apis_datasource_v0alpha1_HealthCheckResult(ref common.ReferenceC
}, },
"details": { "details": {
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
Description: "Spec depends on the the plugin", Description: "Spec depends on the plugin",
Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured"), Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured"),
}, },
}, },

View File

@ -268,7 +268,7 @@ func schema_pkg_apis_query_v0alpha1_QueryTypeDefinition(ref common.ReferenceCall
return common.OpenAPIDefinition{ return common.OpenAPIDefinition{
Schema: spec.Schema{ Schema: spec.Schema{
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
Description: "Generic query request with shared time across all values", Description: "Defines a query behavior in a datasource. This is a similar model to a CRD where the payload describes a valid query",
Type: []string{"object"}, Type: []string{"object"},
Properties: map[string]spec.Schema{ Properties: map[string]spec.Schema{
"kind": { "kind": {

View File

@ -22,8 +22,8 @@ var ScopeResourceInfo = common.NewResourceInfo(GROUP, VERSION,
var ScopeDashboardResourceInfo = common.NewResourceInfo(GROUP, VERSION, var ScopeDashboardResourceInfo = common.NewResourceInfo(GROUP, VERSION,
"scopedashboards", "scopedashboard", "ScopeDashboard", "scopedashboards", "scopedashboard", "ScopeDashboard",
func() runtime.Object { return &ScopeDashboard{} }, func() runtime.Object { return &ScopeDashboardBinding{} },
func() runtime.Object { return &ScopeDashboardList{} }, func() runtime.Object { return &ScopeDashboardBindingList{} },
) )
var ( var (
@ -45,8 +45,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion, scheme.AddKnownTypes(SchemeGroupVersion,
&Scope{}, &Scope{},
&ScopeList{}, &ScopeList{},
&ScopeDashboard{}, &ScopeDashboardBinding{},
&ScopeDashboardList{}, &ScopeDashboardBindingList{},
) )
metav1.AddToGroupVersion(scheme, SchemeGroupVersion) metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil return nil

View File

@ -13,19 +13,33 @@ type Scope struct {
} }
type ScopeSpec struct { type ScopeSpec struct {
Title string `json:"title"` Title string `json:"title"`
Type string `json:"type"` Type string `json:"type"`
Description string `json:"description"` Description string `json:"description"`
Category string `json:"category"` Category string `json:"category"`
Filters []ScopeFilter `json:"filters"`
// +listType=atomic
Filters []ScopeFilter `json:"filters"`
} }
type ScopeFilter struct { type ScopeFilter struct {
Key string `json:"key"` Key string `json:"key"`
Value string `json:"value"` Value string `json:"value"`
Operator string `json:"operator"` 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"
)
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type ScopeList struct { type ScopeList struct {
metav1.TypeMeta `json:",inline"` metav1.TypeMeta `json:",inline"`
@ -35,22 +49,22 @@ type ScopeList struct {
} }
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type ScopeDashboard struct { type ScopeDashboardBinding struct {
metav1.TypeMeta `json:",inline"` metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"` metav1.ObjectMeta `json:"metadata,omitempty"`
Spec ScopeDashboardSpec `json:"spec,omitempty"` Spec ScopeDashboardBindingSpec `json:"spec,omitempty"`
} }
type ScopeDashboardSpec struct { type ScopeDashboardBindingSpec struct {
DashboardUIDs []string `json:"dashboardUids"` Dashboards []string `json:"dashboards"`
ScopeUID string `json:"scopeUid"` Scope string `json:"scope"`
} }
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type ScopeDashboardList struct { type ScopeDashboardBindingList struct {
metav1.TypeMeta `json:",inline"` metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"` metav1.ListMeta `json:"metadata,omitempty"`
Items []ScopeDashboard `json:"items,omitempty"` Items []ScopeDashboardBinding `json:"items,omitempty"`
} }

View File

@ -39,7 +39,7 @@ func (in *Scope) DeepCopyObject() runtime.Object {
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ScopeDashboard) DeepCopyInto(out *ScopeDashboard) { func (in *ScopeDashboardBinding) DeepCopyInto(out *ScopeDashboardBinding) {
*out = *in *out = *in
out.TypeMeta = in.TypeMeta out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
@ -47,18 +47,18 @@ func (in *ScopeDashboard) DeepCopyInto(out *ScopeDashboard) {
return return
} }
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeDashboard. // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeDashboardBinding.
func (in *ScopeDashboard) DeepCopy() *ScopeDashboard { func (in *ScopeDashboardBinding) DeepCopy() *ScopeDashboardBinding {
if in == nil { if in == nil {
return nil return nil
} }
out := new(ScopeDashboard) out := new(ScopeDashboardBinding)
in.DeepCopyInto(out) in.DeepCopyInto(out)
return out return out
} }
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ScopeDashboard) DeepCopyObject() runtime.Object { func (in *ScopeDashboardBinding) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil { if c := in.DeepCopy(); c != nil {
return c return c
} }
@ -66,13 +66,13 @@ func (in *ScopeDashboard) DeepCopyObject() runtime.Object {
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ScopeDashboardList) DeepCopyInto(out *ScopeDashboardList) { func (in *ScopeDashboardBindingList) DeepCopyInto(out *ScopeDashboardBindingList) {
*out = *in *out = *in
out.TypeMeta = in.TypeMeta out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta) in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil { if in.Items != nil {
in, out := &in.Items, &out.Items in, out := &in.Items, &out.Items
*out = make([]ScopeDashboard, len(*in)) *out = make([]ScopeDashboardBinding, len(*in))
for i := range *in { for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i]) (*in)[i].DeepCopyInto(&(*out)[i])
} }
@ -80,18 +80,18 @@ func (in *ScopeDashboardList) DeepCopyInto(out *ScopeDashboardList) {
return return
} }
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeDashboardList. // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeDashboardBindingList.
func (in *ScopeDashboardList) DeepCopy() *ScopeDashboardList { func (in *ScopeDashboardBindingList) DeepCopy() *ScopeDashboardBindingList {
if in == nil { if in == nil {
return nil return nil
} }
out := new(ScopeDashboardList) out := new(ScopeDashboardBindingList)
in.DeepCopyInto(out) in.DeepCopyInto(out)
return out return out
} }
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ScopeDashboardList) DeepCopyObject() runtime.Object { func (in *ScopeDashboardBindingList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil { if c := in.DeepCopy(); c != nil {
return c return c
} }
@ -99,22 +99,22 @@ func (in *ScopeDashboardList) DeepCopyObject() runtime.Object {
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ScopeDashboardSpec) DeepCopyInto(out *ScopeDashboardSpec) { func (in *ScopeDashboardBindingSpec) DeepCopyInto(out *ScopeDashboardBindingSpec) {
*out = *in *out = *in
if in.DashboardUIDs != nil { if in.Dashboards != nil {
in, out := &in.DashboardUIDs, &out.DashboardUIDs in, out := &in.Dashboards, &out.Dashboards
*out = make([]string, len(*in)) *out = make([]string, len(*in))
copy(*out, *in) copy(*out, *in)
} }
return return
} }
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeDashboardSpec. // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeDashboardBindingSpec.
func (in *ScopeDashboardSpec) DeepCopy() *ScopeDashboardSpec { func (in *ScopeDashboardBindingSpec) DeepCopy() *ScopeDashboardBindingSpec {
if in == nil { if in == nil {
return nil return nil
} }
out := new(ScopeDashboardSpec) out := new(ScopeDashboardBindingSpec)
in.DeepCopyInto(out) in.DeepCopyInto(out)
return out return out
} }

View File

@ -16,13 +16,13 @@ import (
func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition { func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition {
return map[string]common.OpenAPIDefinition{ return map[string]common.OpenAPIDefinition{
"github.com/grafana/grafana/pkg/apis/scope/v0alpha1.Scope": schema_pkg_apis_scope_v0alpha1_Scope(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.ScopeDashboard": schema_pkg_apis_scope_v0alpha1_ScopeDashboard(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.ScopeDashboardList": schema_pkg_apis_scope_v0alpha1_ScopeDashboardList(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.ScopeDashboardSpec": schema_pkg_apis_scope_v0alpha1_ScopeDashboardSpec(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.ScopeFilter": schema_pkg_apis_scope_v0alpha1_ScopeFilter(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.ScopeList": schema_pkg_apis_scope_v0alpha1_ScopeList(ref),
"github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeSpec": schema_pkg_apis_scope_v0alpha1_ScopeSpec(ref), "github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeSpec": schema_pkg_apis_scope_v0alpha1_ScopeSpec(ref),
} }
} }
@ -66,7 +66,7 @@ func schema_pkg_apis_scope_v0alpha1_Scope(ref common.ReferenceCallback) common.O
} }
} }
func schema_pkg_apis_scope_v0alpha1_ScopeDashboard(ref common.ReferenceCallback) common.OpenAPIDefinition { func schema_pkg_apis_scope_v0alpha1_ScopeDashboardBinding(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{ return common.OpenAPIDefinition{
Schema: spec.Schema{ Schema: spec.Schema{
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
@ -95,18 +95,18 @@ func schema_pkg_apis_scope_v0alpha1_ScopeDashboard(ref common.ReferenceCallback)
"spec": { "spec": {
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
Default: map[string]interface{}{}, Default: map[string]interface{}{},
Ref: ref("github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboardSpec"), Ref: ref("github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboardBindingSpec"),
}, },
}, },
}, },
}, },
}, },
Dependencies: []string{ Dependencies: []string{
"github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboardSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, "github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboardBindingSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
} }
} }
func schema_pkg_apis_scope_v0alpha1_ScopeDashboardList(ref common.ReferenceCallback) common.OpenAPIDefinition { func schema_pkg_apis_scope_v0alpha1_ScopeDashboardBindingList(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{ return common.OpenAPIDefinition{
Schema: spec.Schema{ Schema: spec.Schema{
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
@ -139,7 +139,7 @@ func schema_pkg_apis_scope_v0alpha1_ScopeDashboardList(ref common.ReferenceCallb
Schema: &spec.Schema{ Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
Default: map[string]interface{}{}, Default: map[string]interface{}{},
Ref: ref("github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboard"), Ref: ref("github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboardBinding"),
}, },
}, },
}, },
@ -149,17 +149,17 @@ func schema_pkg_apis_scope_v0alpha1_ScopeDashboardList(ref common.ReferenceCallb
}, },
}, },
Dependencies: []string{ Dependencies: []string{
"github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboard", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, "github.com/grafana/grafana/pkg/apis/scope/v0alpha1.ScopeDashboardBinding", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"},
} }
} }
func schema_pkg_apis_scope_v0alpha1_ScopeDashboardSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { func schema_pkg_apis_scope_v0alpha1_ScopeDashboardBindingSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{ return common.OpenAPIDefinition{
Schema: spec.Schema{ Schema: spec.Schema{
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
Type: []string{"object"}, Type: []string{"object"},
Properties: map[string]spec.Schema{ Properties: map[string]spec.Schema{
"dashboardUids": { "dashboards": {
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
Type: []string{"array"}, Type: []string{"array"},
Items: &spec.SchemaOrArray{ Items: &spec.SchemaOrArray{
@ -173,7 +173,7 @@ func schema_pkg_apis_scope_v0alpha1_ScopeDashboardSpec(ref common.ReferenceCallb
}, },
}, },
}, },
"scopeUid": { "scope": {
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
Default: "", Default: "",
Type: []string{"string"}, Type: []string{"string"},
@ -181,7 +181,7 @@ func schema_pkg_apis_scope_v0alpha1_ScopeDashboardSpec(ref common.ReferenceCallb
}, },
}, },
}, },
Required: []string{"dashboardUids", "scopeUid"}, Required: []string{"dashboards", "scope"},
}, },
}, },
} }
@ -209,9 +209,11 @@ func schema_pkg_apis_scope_v0alpha1_ScopeFilter(ref common.ReferenceCallback) co
}, },
"operator": { "operator": {
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
Default: "", Description: "Possible enum values:\n - `\"equals\"`\n - `\"not-equals\"`\n - `\"regex-match\"`\n - `\"regex-not-match\"`",
Type: []string{"string"}, Default: "",
Format: "", Type: []string{"string"},
Format: "",
Enum: []interface{}{"equals", "not-equals", "regex-match", "regex-not-match"},
}, },
}, },
}, },
@ -303,6 +305,11 @@ func schema_pkg_apis_scope_v0alpha1_ScopeSpec(ref common.ReferenceCallback) comm
}, },
}, },
"filters": { "filters": {
VendorExtensible: spec.VendorExtensible{
Extensions: spec.Extensions{
"x-kubernetes-list-type": "atomic",
},
},
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
Type: []string{"array"}, Type: []string{"array"},
Items: &spec.SchemaOrArray{ Items: &spec.SchemaOrArray{

View File

@ -1,4 +1 @@
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/scope/v0alpha1,ScopeDashboardSpec,DashboardUIDs API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/scope/v0alpha1,ScopeDashboardBindingSpec,Dashboards
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/scope/v0alpha1,ScopeSpec,Filters
API rule violation: names_match,github.com/grafana/grafana/pkg/apis/scope/v0alpha1,ScopeDashboardSpec,DashboardUIDs
API rule violation: names_match,github.com/grafana/grafana/pkg/apis/scope/v0alpha1,ScopeDashboardSpec,ScopeUID

View File

@ -58,13 +58,10 @@ export class ScopesDashboardsScene extends SceneObjectBase<ScopesDashboardsScene
private async fetchDashboardsUids(scope: string): Promise<string[]> { private async fetchDashboardsUids(scope: string): Promise<string[]> {
try { try {
const response = await getBackendSrv().get<{ const response = await getBackendSrv().get<{
items: Array<{ spec: { dashboardUids: null | string[]; scopeUid: string } }>; items: Array<{ spec: { dashboards: null | string[]; scope: string } }>;
}>(this._url, { scope }); }>(this._url, { scope });
return ( return response.items.find((item) => !!item.spec.dashboards && item.spec.scope === scope)?.spec.dashboards ?? [];
response.items.find((item) => !!item.spec.dashboardUids && item.spec.scopeUid === scope)?.spec.dashboardUids ??
[]
);
} catch (err) { } catch (err) {
return []; return [];
} }

View File

@ -92,8 +92,8 @@ jest.mock('@grafana/runtime', () => ({
return { return {
items: Object.values(scopesMocks).map((scope) => ({ items: Object.values(scopesMocks).map((scope) => ({
spec: { spec: {
dashboardUids: scope.dashboards.map((dashboard) => dashboard.uid), dashboards: scope.dashboards.map((dashboard) => dashboard.uid),
scopeUid: scope.uid, scope: scope.uid,
}, },
})), })),
}; };