diff --git a/pkg/apimachinery/apis/common/v0alpha1/unstructured.go b/pkg/apimachinery/apis/common/v0alpha1/unstructured.go index af26531c59a..e779c5fafd3 100644 --- a/pkg/apimachinery/apis/common/v0alpha1/unstructured.go +++ b/pkg/apimachinery/apis/common/v0alpha1/unstructured.go @@ -14,7 +14,7 @@ import ( type Unstructured struct { // Object is a JSON compatible map with string, float, int, bool, []interface{}, // or map[string]interface{} children. - Object map[string]any + Object map[string]interface{} } // Produce an API definition that represents map[string]any diff --git a/pkg/apis/dashboard/doc.go b/pkg/apis/dashboard/doc.go new file mode 100644 index 00000000000..d2ba2d03445 --- /dev/null +++ b/pkg/apis/dashboard/doc.go @@ -0,0 +1,4 @@ +// +k8s:deepcopy-gen=package +// +groupName=dashboard.grafana.app + +package dashboard // import "github.com/grafana/grafana/pkg/apis/dashboard" diff --git a/pkg/apis/dashboard/register.go b/pkg/apis/dashboard/register.go new file mode 100644 index 00000000000..2c7cf8d8b4d --- /dev/null +++ b/pkg/apis/dashboard/register.go @@ -0,0 +1,92 @@ +package dashboard + +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 = "dashboard.grafana.app" + VERSION = runtime.APIVersionInternal + APIVERSION = GROUP + "/" + VERSION +) + +var DashboardResourceInfo = utils.NewResourceInfo(GROUP, VERSION, + "dashboards", "dashboard", "Dashboard", + func() runtime.Object { return &Dashboard{} }, + func() runtime.Object { return &DashboardList{} }, + utils.TableColumns{ + Definition: []metav1.TableColumnDefinition{ + {Name: "Name", Type: "string", Format: "name"}, + {Name: "Title", Type: "string", Format: "string", Description: "The dashboard name"}, + {Name: "Created At", Type: "date"}, + }, + Reader: func(obj any) ([]interface{}, error) { + dash, ok := obj.(*Dashboard) + if ok { + if dash != nil { + return []interface{}{ + dash.Name, + dash.Spec.GetNestedString("title"), + dash.CreationTimestamp.UTC().Format(time.RFC3339), + }, nil + } + } + return nil, fmt.Errorf("expected dashboard") + }, + }, +) + +var LibraryPanelResourceInfo = utils.NewResourceInfo(GROUP, VERSION, + "librarypanels", "librarypanel", "LibraryPanel", + func() runtime.Object { return &LibraryPanel{} }, + func() runtime.Object { return &LibraryPanelList{} }, + utils.TableColumns{ + Definition: []metav1.TableColumnDefinition{ + {Name: "Name", Type: "string", Format: "name"}, + {Name: "Title", Type: "string", Description: "The dashboard name"}, + {Name: "Type", Type: "string", Description: "the panel type"}, + {Name: "Created At", Type: "date"}, + }, + Reader: func(obj any) ([]interface{}, error) { + dash, ok := obj.(*LibraryPanel) + if ok { + if dash != nil { + return []interface{}{ + dash.Name, + dash.Spec.Title, + dash.Spec.Type, + dash.CreationTimestamp.UTC().Format(time.RFC3339), + }, nil + } + } + return nil, fmt.Errorf("expected library panel") + }, + }, +) + +var ( + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme + schemaGroupVersion = schema.GroupVersion{Group: GROUP, Version: VERSION} +) + +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(schemaGroupVersion, + &Dashboard{}, + &DashboardList{}, + &DashboardWithAccessInfo{}, + &DashboardVersionList{}, + &VersionsQueryOptions{}, + &LibraryPanel{}, + &LibraryPanelList{}, + &metav1.PartialObjectMetadata{}, + &metav1.PartialObjectMetadataList{}, + ) + return nil +} diff --git a/pkg/apis/dashboard/types.go b/pkg/apis/dashboard/types.go new file mode 100644 index 00000000000..1d565fa000e --- /dev/null +++ b/pkg/apis/dashboard/types.go @@ -0,0 +1,161 @@ +package dashboard + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + data "github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1" + common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type Dashboard struct { + metav1.TypeMeta `json:",inline"` + // Standard object's metadata + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // The dashboard body (unstructured for now) + Spec common.Unstructured `json:"spec"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type DashboardList struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ListMeta `json:"metadata,omitempty"` + + Items []Dashboard `json:"items,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type DashboardVersionList struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ListMeta `json:"metadata,omitempty"` + + Items []DashboardVersionInfo `json:"items,omitempty"` +} + +type DashboardVersionInfo struct { + // The internal ID for this version (will be replaced with resourceVersion) + Version int `json:"version"` + + // If the dashboard came from a previous version, it is set here + ParentVersion int `json:"parentVersion,omitempty"` + + // The creation timestamp for this version + Created int64 `json:"created"` + + // The user who created this version + CreatedBy string `json:"createdBy,omitempty"` + + // Message passed while saving the version + Message string `json:"message,omitempty"` +} + +// +k8s:conversion-gen:explicit-from=net/url.Values +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type VersionsQueryOptions struct { + metav1.TypeMeta `json:",inline"` + + // Path is the URL path + // +optional + Path string `json:"path,omitempty"` + + // +optional + Version int64 `json:"version,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type LibraryPanel struct { + metav1.TypeMeta `json:",inline"` + // Standard object's metadata + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Panel properties + Spec LibraryPanelSpec `json:"spec"` + + // Status will show errors + Status *LibraryPanelStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type LibraryPanelList struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ListMeta `json:"metadata,omitempty"` + + Items []LibraryPanel `json:"items,omitempty"` +} + +type LibraryPanelSpec struct { + // The panel type + Type string `json:"type"` + + // The panel type + PluginVersion string `json:"pluginVersion,omitempty"` + + // The panel title + Title string `json:"title,omitempty"` + + // Library panel description + Description string `json:"description,omitempty"` + + // The options schema depends on the panel type + Options common.Unstructured `json:"options"` + + // The fieldConfig schema depends on the panel type + FieldConfig common.Unstructured `json:"fieldConfig"` + + // The default datasource type + Datasource *data.DataSourceRef `json:"datasource,omitempty"` + + // The datasource queries + // +listType=set + Targets []data.DataQuery `json:"targets,omitempty"` +} + +type LibraryPanelStatus struct { + // Translation warnings (mostly things that were in SQL columns but not found in the saved body) + Warnings []string `json:"warnings,omitempty"` + + // The properties previously stored in SQL that are not included in this model + Missing common.Unstructured `json:"missing,omitempty"` +} + +// This is like the legacy DTO where access and metadata are all returned in a single call +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type DashboardWithAccessInfo struct { + Dashboard `json:",inline"` + + Access DashboardAccess `json:"access"` +} + +// Information about how the requesting user can use a given dashboard +type DashboardAccess struct { + // Metadata fields + Slug string `json:"slug,omitempty"` + Url string `json:"url,omitempty"` + + // The permissions part + CanSave bool `json:"canSave"` + CanEdit bool `json:"canEdit"` + CanAdmin bool `json:"canAdmin"` + CanStar bool `json:"canStar"` + CanDelete bool `json:"canDelete"` + AnnotationsPermissions *AnnotationPermission `json:"annotationsPermissions"` +} + +type AnnotationPermission struct { + Dashboard AnnotationActions `json:"dashboard"` + Organization AnnotationActions `json:"organization"` +} + +type AnnotationActions struct { + CanAdd bool `json:"canAdd"` + CanEdit bool `json:"canEdit"` + CanDelete bool `json:"canDelete"` +} diff --git a/pkg/apis/dashboard/v0alpha1/doc.go b/pkg/apis/dashboard/v0alpha1/doc.go index 92822b1a59e..5716d920d2a 100644 --- a/pkg/apis/dashboard/v0alpha1/doc.go +++ b/pkg/apis/dashboard/v0alpha1/doc.go @@ -1,6 +1,7 @@ // +k8s:deepcopy-gen=package // +k8s:openapi-gen=true // +k8s:defaulter-gen=TypeMeta +// +k8s:conversion-gen=github.com/grafana/grafana/pkg/apis/dashboard // +groupName=dashboard.grafana.app package v0alpha1 // import "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1" diff --git a/pkg/apis/dashboard/v0alpha1/register.go b/pkg/apis/dashboard/v0alpha1/register.go index 9b8fe08536d..f2829c986a5 100644 --- a/pkg/apis/dashboard/v0alpha1/register.go +++ b/pkg/apis/dashboard/v0alpha1/register.go @@ -71,6 +71,33 @@ var LibraryPanelResourceInfo = utils.NewResourceInfo(GROUP, VERSION, ) var ( - // SchemeGroupVersion is group version used to register these objects - SchemeGroupVersion = schema.GroupVersion{Group: GROUP, Version: VERSION} + SchemeBuilder runtime.SchemeBuilder + localSchemeBuilder = &SchemeBuilder + AddToScheme = localSchemeBuilder.AddToScheme + schemeGroupVersion = schema.GroupVersion{Group: GROUP, Version: VERSION} ) + +func init() { + localSchemeBuilder.Register(addKnownTypes, addDefaultingFuncs) +} + +// Adds the list of known types to the given scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(schemeGroupVersion, + &Dashboard{}, + &DashboardList{}, + &DashboardWithAccessInfo{}, + &DashboardVersionList{}, + &VersionsQueryOptions{}, + &LibraryPanel{}, + &LibraryPanelList{}, + &metav1.PartialObjectMetadata{}, + &metav1.PartialObjectMetadataList{}, + ) + metav1.AddToGroupVersion(scheme, schemeGroupVersion) + return nil +} + +func addDefaultingFuncs(scheme *runtime.Scheme) error { + return RegisterDefaults(scheme) +} diff --git a/pkg/apis/dashboard/v0alpha1/zz_generated.conversion.go b/pkg/apis/dashboard/v0alpha1/zz_generated.conversion.go new file mode 100644 index 00000000000..70b458a0fa9 --- /dev/null +++ b/pkg/apis/dashboard/v0alpha1/zz_generated.conversion.go @@ -0,0 +1,528 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// SPDX-License-Identifier: AGPL-3.0-only + +// Code generated by conversion-gen. DO NOT EDIT. + +package v0alpha1 + +import ( + url "net/url" + unsafe "unsafe" + + datav0alpha1 "github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1" + dashboard "github.com/grafana/grafana/pkg/apis/dashboard" + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*AnnotationActions)(nil), (*dashboard.AnnotationActions)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v0alpha1_AnnotationActions_To_dashboard_AnnotationActions(a.(*AnnotationActions), b.(*dashboard.AnnotationActions), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.AnnotationActions)(nil), (*AnnotationActions)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_AnnotationActions_To_v0alpha1_AnnotationActions(a.(*dashboard.AnnotationActions), b.(*AnnotationActions), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*AnnotationPermission)(nil), (*dashboard.AnnotationPermission)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v0alpha1_AnnotationPermission_To_dashboard_AnnotationPermission(a.(*AnnotationPermission), b.(*dashboard.AnnotationPermission), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.AnnotationPermission)(nil), (*AnnotationPermission)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_AnnotationPermission_To_v0alpha1_AnnotationPermission(a.(*dashboard.AnnotationPermission), b.(*AnnotationPermission), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*Dashboard)(nil), (*dashboard.Dashboard)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v0alpha1_Dashboard_To_dashboard_Dashboard(a.(*Dashboard), b.(*dashboard.Dashboard), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.Dashboard)(nil), (*Dashboard)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_Dashboard_To_v0alpha1_Dashboard(a.(*dashboard.Dashboard), b.(*Dashboard), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DashboardAccess)(nil), (*dashboard.DashboardAccess)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v0alpha1_DashboardAccess_To_dashboard_DashboardAccess(a.(*DashboardAccess), b.(*dashboard.DashboardAccess), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.DashboardAccess)(nil), (*DashboardAccess)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_DashboardAccess_To_v0alpha1_DashboardAccess(a.(*dashboard.DashboardAccess), b.(*DashboardAccess), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DashboardList)(nil), (*dashboard.DashboardList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v0alpha1_DashboardList_To_dashboard_DashboardList(a.(*DashboardList), b.(*dashboard.DashboardList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.DashboardList)(nil), (*DashboardList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_DashboardList_To_v0alpha1_DashboardList(a.(*dashboard.DashboardList), b.(*DashboardList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DashboardVersionInfo)(nil), (*dashboard.DashboardVersionInfo)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v0alpha1_DashboardVersionInfo_To_dashboard_DashboardVersionInfo(a.(*DashboardVersionInfo), b.(*dashboard.DashboardVersionInfo), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.DashboardVersionInfo)(nil), (*DashboardVersionInfo)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_DashboardVersionInfo_To_v0alpha1_DashboardVersionInfo(a.(*dashboard.DashboardVersionInfo), b.(*DashboardVersionInfo), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DashboardVersionList)(nil), (*dashboard.DashboardVersionList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v0alpha1_DashboardVersionList_To_dashboard_DashboardVersionList(a.(*DashboardVersionList), b.(*dashboard.DashboardVersionList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.DashboardVersionList)(nil), (*DashboardVersionList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_DashboardVersionList_To_v0alpha1_DashboardVersionList(a.(*dashboard.DashboardVersionList), b.(*DashboardVersionList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DashboardWithAccessInfo)(nil), (*dashboard.DashboardWithAccessInfo)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v0alpha1_DashboardWithAccessInfo_To_dashboard_DashboardWithAccessInfo(a.(*DashboardWithAccessInfo), b.(*dashboard.DashboardWithAccessInfo), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.DashboardWithAccessInfo)(nil), (*DashboardWithAccessInfo)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_DashboardWithAccessInfo_To_v0alpha1_DashboardWithAccessInfo(a.(*dashboard.DashboardWithAccessInfo), b.(*DashboardWithAccessInfo), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*LibraryPanel)(nil), (*dashboard.LibraryPanel)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v0alpha1_LibraryPanel_To_dashboard_LibraryPanel(a.(*LibraryPanel), b.(*dashboard.LibraryPanel), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.LibraryPanel)(nil), (*LibraryPanel)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_LibraryPanel_To_v0alpha1_LibraryPanel(a.(*dashboard.LibraryPanel), b.(*LibraryPanel), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*LibraryPanelList)(nil), (*dashboard.LibraryPanelList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v0alpha1_LibraryPanelList_To_dashboard_LibraryPanelList(a.(*LibraryPanelList), b.(*dashboard.LibraryPanelList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.LibraryPanelList)(nil), (*LibraryPanelList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_LibraryPanelList_To_v0alpha1_LibraryPanelList(a.(*dashboard.LibraryPanelList), b.(*LibraryPanelList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*LibraryPanelSpec)(nil), (*dashboard.LibraryPanelSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v0alpha1_LibraryPanelSpec_To_dashboard_LibraryPanelSpec(a.(*LibraryPanelSpec), b.(*dashboard.LibraryPanelSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.LibraryPanelSpec)(nil), (*LibraryPanelSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_LibraryPanelSpec_To_v0alpha1_LibraryPanelSpec(a.(*dashboard.LibraryPanelSpec), b.(*LibraryPanelSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*LibraryPanelStatus)(nil), (*dashboard.LibraryPanelStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v0alpha1_LibraryPanelStatus_To_dashboard_LibraryPanelStatus(a.(*LibraryPanelStatus), b.(*dashboard.LibraryPanelStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.LibraryPanelStatus)(nil), (*LibraryPanelStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_LibraryPanelStatus_To_v0alpha1_LibraryPanelStatus(a.(*dashboard.LibraryPanelStatus), b.(*LibraryPanelStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*VersionsQueryOptions)(nil), (*dashboard.VersionsQueryOptions)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v0alpha1_VersionsQueryOptions_To_dashboard_VersionsQueryOptions(a.(*VersionsQueryOptions), b.(*dashboard.VersionsQueryOptions), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.VersionsQueryOptions)(nil), (*VersionsQueryOptions)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_VersionsQueryOptions_To_v0alpha1_VersionsQueryOptions(a.(*dashboard.VersionsQueryOptions), b.(*VersionsQueryOptions), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*url.Values)(nil), (*VersionsQueryOptions)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_url_Values_To_v0alpha1_VersionsQueryOptions(a.(*url.Values), b.(*VersionsQueryOptions), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v0alpha1_AnnotationActions_To_dashboard_AnnotationActions(in *AnnotationActions, out *dashboard.AnnotationActions, s conversion.Scope) error { + out.CanAdd = in.CanAdd + out.CanEdit = in.CanEdit + out.CanDelete = in.CanDelete + return nil +} + +// Convert_v0alpha1_AnnotationActions_To_dashboard_AnnotationActions is an autogenerated conversion function. +func Convert_v0alpha1_AnnotationActions_To_dashboard_AnnotationActions(in *AnnotationActions, out *dashboard.AnnotationActions, s conversion.Scope) error { + return autoConvert_v0alpha1_AnnotationActions_To_dashboard_AnnotationActions(in, out, s) +} + +func autoConvert_dashboard_AnnotationActions_To_v0alpha1_AnnotationActions(in *dashboard.AnnotationActions, out *AnnotationActions, s conversion.Scope) error { + out.CanAdd = in.CanAdd + out.CanEdit = in.CanEdit + out.CanDelete = in.CanDelete + return nil +} + +// Convert_dashboard_AnnotationActions_To_v0alpha1_AnnotationActions is an autogenerated conversion function. +func Convert_dashboard_AnnotationActions_To_v0alpha1_AnnotationActions(in *dashboard.AnnotationActions, out *AnnotationActions, s conversion.Scope) error { + return autoConvert_dashboard_AnnotationActions_To_v0alpha1_AnnotationActions(in, out, s) +} + +func autoConvert_v0alpha1_AnnotationPermission_To_dashboard_AnnotationPermission(in *AnnotationPermission, out *dashboard.AnnotationPermission, s conversion.Scope) error { + if err := Convert_v0alpha1_AnnotationActions_To_dashboard_AnnotationActions(&in.Dashboard, &out.Dashboard, s); err != nil { + return err + } + if err := Convert_v0alpha1_AnnotationActions_To_dashboard_AnnotationActions(&in.Organization, &out.Organization, s); err != nil { + return err + } + return nil +} + +// Convert_v0alpha1_AnnotationPermission_To_dashboard_AnnotationPermission is an autogenerated conversion function. +func Convert_v0alpha1_AnnotationPermission_To_dashboard_AnnotationPermission(in *AnnotationPermission, out *dashboard.AnnotationPermission, s conversion.Scope) error { + return autoConvert_v0alpha1_AnnotationPermission_To_dashboard_AnnotationPermission(in, out, s) +} + +func autoConvert_dashboard_AnnotationPermission_To_v0alpha1_AnnotationPermission(in *dashboard.AnnotationPermission, out *AnnotationPermission, s conversion.Scope) error { + if err := Convert_dashboard_AnnotationActions_To_v0alpha1_AnnotationActions(&in.Dashboard, &out.Dashboard, s); err != nil { + return err + } + if err := Convert_dashboard_AnnotationActions_To_v0alpha1_AnnotationActions(&in.Organization, &out.Organization, s); err != nil { + return err + } + return nil +} + +// Convert_dashboard_AnnotationPermission_To_v0alpha1_AnnotationPermission is an autogenerated conversion function. +func Convert_dashboard_AnnotationPermission_To_v0alpha1_AnnotationPermission(in *dashboard.AnnotationPermission, out *AnnotationPermission, s conversion.Scope) error { + return autoConvert_dashboard_AnnotationPermission_To_v0alpha1_AnnotationPermission(in, out, s) +} + +func autoConvert_v0alpha1_Dashboard_To_dashboard_Dashboard(in *Dashboard, out *dashboard.Dashboard, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + out.Spec = in.Spec + return nil +} + +// Convert_v0alpha1_Dashboard_To_dashboard_Dashboard is an autogenerated conversion function. +func Convert_v0alpha1_Dashboard_To_dashboard_Dashboard(in *Dashboard, out *dashboard.Dashboard, s conversion.Scope) error { + return autoConvert_v0alpha1_Dashboard_To_dashboard_Dashboard(in, out, s) +} + +func autoConvert_dashboard_Dashboard_To_v0alpha1_Dashboard(in *dashboard.Dashboard, out *Dashboard, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + out.Spec = in.Spec + return nil +} + +// Convert_dashboard_Dashboard_To_v0alpha1_Dashboard is an autogenerated conversion function. +func Convert_dashboard_Dashboard_To_v0alpha1_Dashboard(in *dashboard.Dashboard, out *Dashboard, s conversion.Scope) error { + return autoConvert_dashboard_Dashboard_To_v0alpha1_Dashboard(in, out, s) +} + +func autoConvert_v0alpha1_DashboardAccess_To_dashboard_DashboardAccess(in *DashboardAccess, out *dashboard.DashboardAccess, s conversion.Scope) error { + out.Slug = in.Slug + out.Url = in.Url + out.CanSave = in.CanSave + out.CanEdit = in.CanEdit + out.CanAdmin = in.CanAdmin + out.CanStar = in.CanStar + out.CanDelete = in.CanDelete + out.AnnotationsPermissions = (*dashboard.AnnotationPermission)(unsafe.Pointer(in.AnnotationsPermissions)) + return nil +} + +// Convert_v0alpha1_DashboardAccess_To_dashboard_DashboardAccess is an autogenerated conversion function. +func Convert_v0alpha1_DashboardAccess_To_dashboard_DashboardAccess(in *DashboardAccess, out *dashboard.DashboardAccess, s conversion.Scope) error { + return autoConvert_v0alpha1_DashboardAccess_To_dashboard_DashboardAccess(in, out, s) +} + +func autoConvert_dashboard_DashboardAccess_To_v0alpha1_DashboardAccess(in *dashboard.DashboardAccess, out *DashboardAccess, s conversion.Scope) error { + out.Slug = in.Slug + out.Url = in.Url + out.CanSave = in.CanSave + out.CanEdit = in.CanEdit + out.CanAdmin = in.CanAdmin + out.CanStar = in.CanStar + out.CanDelete = in.CanDelete + out.AnnotationsPermissions = (*AnnotationPermission)(unsafe.Pointer(in.AnnotationsPermissions)) + return nil +} + +// Convert_dashboard_DashboardAccess_To_v0alpha1_DashboardAccess is an autogenerated conversion function. +func Convert_dashboard_DashboardAccess_To_v0alpha1_DashboardAccess(in *dashboard.DashboardAccess, out *DashboardAccess, s conversion.Scope) error { + return autoConvert_dashboard_DashboardAccess_To_v0alpha1_DashboardAccess(in, out, s) +} + +func autoConvert_v0alpha1_DashboardList_To_dashboard_DashboardList(in *DashboardList, out *dashboard.DashboardList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]dashboard.Dashboard)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_v0alpha1_DashboardList_To_dashboard_DashboardList is an autogenerated conversion function. +func Convert_v0alpha1_DashboardList_To_dashboard_DashboardList(in *DashboardList, out *dashboard.DashboardList, s conversion.Scope) error { + return autoConvert_v0alpha1_DashboardList_To_dashboard_DashboardList(in, out, s) +} + +func autoConvert_dashboard_DashboardList_To_v0alpha1_DashboardList(in *dashboard.DashboardList, out *DashboardList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]Dashboard)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_dashboard_DashboardList_To_v0alpha1_DashboardList is an autogenerated conversion function. +func Convert_dashboard_DashboardList_To_v0alpha1_DashboardList(in *dashboard.DashboardList, out *DashboardList, s conversion.Scope) error { + return autoConvert_dashboard_DashboardList_To_v0alpha1_DashboardList(in, out, s) +} + +func autoConvert_v0alpha1_DashboardVersionInfo_To_dashboard_DashboardVersionInfo(in *DashboardVersionInfo, out *dashboard.DashboardVersionInfo, s conversion.Scope) error { + out.Version = in.Version + out.ParentVersion = in.ParentVersion + out.Created = in.Created + out.CreatedBy = in.CreatedBy + out.Message = in.Message + return nil +} + +// Convert_v0alpha1_DashboardVersionInfo_To_dashboard_DashboardVersionInfo is an autogenerated conversion function. +func Convert_v0alpha1_DashboardVersionInfo_To_dashboard_DashboardVersionInfo(in *DashboardVersionInfo, out *dashboard.DashboardVersionInfo, s conversion.Scope) error { + return autoConvert_v0alpha1_DashboardVersionInfo_To_dashboard_DashboardVersionInfo(in, out, s) +} + +func autoConvert_dashboard_DashboardVersionInfo_To_v0alpha1_DashboardVersionInfo(in *dashboard.DashboardVersionInfo, out *DashboardVersionInfo, s conversion.Scope) error { + out.Version = in.Version + out.ParentVersion = in.ParentVersion + out.Created = in.Created + out.CreatedBy = in.CreatedBy + out.Message = in.Message + return nil +} + +// Convert_dashboard_DashboardVersionInfo_To_v0alpha1_DashboardVersionInfo is an autogenerated conversion function. +func Convert_dashboard_DashboardVersionInfo_To_v0alpha1_DashboardVersionInfo(in *dashboard.DashboardVersionInfo, out *DashboardVersionInfo, s conversion.Scope) error { + return autoConvert_dashboard_DashboardVersionInfo_To_v0alpha1_DashboardVersionInfo(in, out, s) +} + +func autoConvert_v0alpha1_DashboardVersionList_To_dashboard_DashboardVersionList(in *DashboardVersionList, out *dashboard.DashboardVersionList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]dashboard.DashboardVersionInfo)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_v0alpha1_DashboardVersionList_To_dashboard_DashboardVersionList is an autogenerated conversion function. +func Convert_v0alpha1_DashboardVersionList_To_dashboard_DashboardVersionList(in *DashboardVersionList, out *dashboard.DashboardVersionList, s conversion.Scope) error { + return autoConvert_v0alpha1_DashboardVersionList_To_dashboard_DashboardVersionList(in, out, s) +} + +func autoConvert_dashboard_DashboardVersionList_To_v0alpha1_DashboardVersionList(in *dashboard.DashboardVersionList, out *DashboardVersionList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]DashboardVersionInfo)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_dashboard_DashboardVersionList_To_v0alpha1_DashboardVersionList is an autogenerated conversion function. +func Convert_dashboard_DashboardVersionList_To_v0alpha1_DashboardVersionList(in *dashboard.DashboardVersionList, out *DashboardVersionList, s conversion.Scope) error { + return autoConvert_dashboard_DashboardVersionList_To_v0alpha1_DashboardVersionList(in, out, s) +} + +func autoConvert_v0alpha1_DashboardWithAccessInfo_To_dashboard_DashboardWithAccessInfo(in *DashboardWithAccessInfo, out *dashboard.DashboardWithAccessInfo, s conversion.Scope) error { + if err := Convert_v0alpha1_Dashboard_To_dashboard_Dashboard(&in.Dashboard, &out.Dashboard, s); err != nil { + return err + } + if err := Convert_v0alpha1_DashboardAccess_To_dashboard_DashboardAccess(&in.Access, &out.Access, s); err != nil { + return err + } + return nil +} + +// Convert_v0alpha1_DashboardWithAccessInfo_To_dashboard_DashboardWithAccessInfo is an autogenerated conversion function. +func Convert_v0alpha1_DashboardWithAccessInfo_To_dashboard_DashboardWithAccessInfo(in *DashboardWithAccessInfo, out *dashboard.DashboardWithAccessInfo, s conversion.Scope) error { + return autoConvert_v0alpha1_DashboardWithAccessInfo_To_dashboard_DashboardWithAccessInfo(in, out, s) +} + +func autoConvert_dashboard_DashboardWithAccessInfo_To_v0alpha1_DashboardWithAccessInfo(in *dashboard.DashboardWithAccessInfo, out *DashboardWithAccessInfo, s conversion.Scope) error { + if err := Convert_dashboard_Dashboard_To_v0alpha1_Dashboard(&in.Dashboard, &out.Dashboard, s); err != nil { + return err + } + if err := Convert_dashboard_DashboardAccess_To_v0alpha1_DashboardAccess(&in.Access, &out.Access, s); err != nil { + return err + } + return nil +} + +// Convert_dashboard_DashboardWithAccessInfo_To_v0alpha1_DashboardWithAccessInfo is an autogenerated conversion function. +func Convert_dashboard_DashboardWithAccessInfo_To_v0alpha1_DashboardWithAccessInfo(in *dashboard.DashboardWithAccessInfo, out *DashboardWithAccessInfo, s conversion.Scope) error { + return autoConvert_dashboard_DashboardWithAccessInfo_To_v0alpha1_DashboardWithAccessInfo(in, out, s) +} + +func autoConvert_v0alpha1_LibraryPanel_To_dashboard_LibraryPanel(in *LibraryPanel, out *dashboard.LibraryPanel, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v0alpha1_LibraryPanelSpec_To_dashboard_LibraryPanelSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + out.Status = (*dashboard.LibraryPanelStatus)(unsafe.Pointer(in.Status)) + return nil +} + +// Convert_v0alpha1_LibraryPanel_To_dashboard_LibraryPanel is an autogenerated conversion function. +func Convert_v0alpha1_LibraryPanel_To_dashboard_LibraryPanel(in *LibraryPanel, out *dashboard.LibraryPanel, s conversion.Scope) error { + return autoConvert_v0alpha1_LibraryPanel_To_dashboard_LibraryPanel(in, out, s) +} + +func autoConvert_dashboard_LibraryPanel_To_v0alpha1_LibraryPanel(in *dashboard.LibraryPanel, out *LibraryPanel, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_dashboard_LibraryPanelSpec_To_v0alpha1_LibraryPanelSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + out.Status = (*LibraryPanelStatus)(unsafe.Pointer(in.Status)) + return nil +} + +// Convert_dashboard_LibraryPanel_To_v0alpha1_LibraryPanel is an autogenerated conversion function. +func Convert_dashboard_LibraryPanel_To_v0alpha1_LibraryPanel(in *dashboard.LibraryPanel, out *LibraryPanel, s conversion.Scope) error { + return autoConvert_dashboard_LibraryPanel_To_v0alpha1_LibraryPanel(in, out, s) +} + +func autoConvert_v0alpha1_LibraryPanelList_To_dashboard_LibraryPanelList(in *LibraryPanelList, out *dashboard.LibraryPanelList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]dashboard.LibraryPanel)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_v0alpha1_LibraryPanelList_To_dashboard_LibraryPanelList is an autogenerated conversion function. +func Convert_v0alpha1_LibraryPanelList_To_dashboard_LibraryPanelList(in *LibraryPanelList, out *dashboard.LibraryPanelList, s conversion.Scope) error { + return autoConvert_v0alpha1_LibraryPanelList_To_dashboard_LibraryPanelList(in, out, s) +} + +func autoConvert_dashboard_LibraryPanelList_To_v0alpha1_LibraryPanelList(in *dashboard.LibraryPanelList, out *LibraryPanelList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]LibraryPanel)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_dashboard_LibraryPanelList_To_v0alpha1_LibraryPanelList is an autogenerated conversion function. +func Convert_dashboard_LibraryPanelList_To_v0alpha1_LibraryPanelList(in *dashboard.LibraryPanelList, out *LibraryPanelList, s conversion.Scope) error { + return autoConvert_dashboard_LibraryPanelList_To_v0alpha1_LibraryPanelList(in, out, s) +} + +func autoConvert_v0alpha1_LibraryPanelSpec_To_dashboard_LibraryPanelSpec(in *LibraryPanelSpec, out *dashboard.LibraryPanelSpec, s conversion.Scope) error { + out.Type = in.Type + out.PluginVersion = in.PluginVersion + out.Title = in.Title + out.Description = in.Description + out.Options = in.Options + out.FieldConfig = in.FieldConfig + out.Datasource = (*datav0alpha1.DataSourceRef)(unsafe.Pointer(in.Datasource)) + out.Targets = *(*[]datav0alpha1.DataQuery)(unsafe.Pointer(&in.Targets)) + return nil +} + +// Convert_v0alpha1_LibraryPanelSpec_To_dashboard_LibraryPanelSpec is an autogenerated conversion function. +func Convert_v0alpha1_LibraryPanelSpec_To_dashboard_LibraryPanelSpec(in *LibraryPanelSpec, out *dashboard.LibraryPanelSpec, s conversion.Scope) error { + return autoConvert_v0alpha1_LibraryPanelSpec_To_dashboard_LibraryPanelSpec(in, out, s) +} + +func autoConvert_dashboard_LibraryPanelSpec_To_v0alpha1_LibraryPanelSpec(in *dashboard.LibraryPanelSpec, out *LibraryPanelSpec, s conversion.Scope) error { + out.Type = in.Type + out.PluginVersion = in.PluginVersion + out.Title = in.Title + out.Description = in.Description + out.Options = in.Options + out.FieldConfig = in.FieldConfig + out.Datasource = (*datav0alpha1.DataSourceRef)(unsafe.Pointer(in.Datasource)) + out.Targets = *(*[]datav0alpha1.DataQuery)(unsafe.Pointer(&in.Targets)) + return nil +} + +// Convert_dashboard_LibraryPanelSpec_To_v0alpha1_LibraryPanelSpec is an autogenerated conversion function. +func Convert_dashboard_LibraryPanelSpec_To_v0alpha1_LibraryPanelSpec(in *dashboard.LibraryPanelSpec, out *LibraryPanelSpec, s conversion.Scope) error { + return autoConvert_dashboard_LibraryPanelSpec_To_v0alpha1_LibraryPanelSpec(in, out, s) +} + +func autoConvert_v0alpha1_LibraryPanelStatus_To_dashboard_LibraryPanelStatus(in *LibraryPanelStatus, out *dashboard.LibraryPanelStatus, s conversion.Scope) error { + out.Warnings = *(*[]string)(unsafe.Pointer(&in.Warnings)) + out.Missing = in.Missing + return nil +} + +// Convert_v0alpha1_LibraryPanelStatus_To_dashboard_LibraryPanelStatus is an autogenerated conversion function. +func Convert_v0alpha1_LibraryPanelStatus_To_dashboard_LibraryPanelStatus(in *LibraryPanelStatus, out *dashboard.LibraryPanelStatus, s conversion.Scope) error { + return autoConvert_v0alpha1_LibraryPanelStatus_To_dashboard_LibraryPanelStatus(in, out, s) +} + +func autoConvert_dashboard_LibraryPanelStatus_To_v0alpha1_LibraryPanelStatus(in *dashboard.LibraryPanelStatus, out *LibraryPanelStatus, s conversion.Scope) error { + out.Warnings = *(*[]string)(unsafe.Pointer(&in.Warnings)) + out.Missing = in.Missing + return nil +} + +// Convert_dashboard_LibraryPanelStatus_To_v0alpha1_LibraryPanelStatus is an autogenerated conversion function. +func Convert_dashboard_LibraryPanelStatus_To_v0alpha1_LibraryPanelStatus(in *dashboard.LibraryPanelStatus, out *LibraryPanelStatus, s conversion.Scope) error { + return autoConvert_dashboard_LibraryPanelStatus_To_v0alpha1_LibraryPanelStatus(in, out, s) +} + +func autoConvert_v0alpha1_VersionsQueryOptions_To_dashboard_VersionsQueryOptions(in *VersionsQueryOptions, out *dashboard.VersionsQueryOptions, s conversion.Scope) error { + out.Path = in.Path + out.Version = in.Version + return nil +} + +// Convert_v0alpha1_VersionsQueryOptions_To_dashboard_VersionsQueryOptions is an autogenerated conversion function. +func Convert_v0alpha1_VersionsQueryOptions_To_dashboard_VersionsQueryOptions(in *VersionsQueryOptions, out *dashboard.VersionsQueryOptions, s conversion.Scope) error { + return autoConvert_v0alpha1_VersionsQueryOptions_To_dashboard_VersionsQueryOptions(in, out, s) +} + +func autoConvert_dashboard_VersionsQueryOptions_To_v0alpha1_VersionsQueryOptions(in *dashboard.VersionsQueryOptions, out *VersionsQueryOptions, s conversion.Scope) error { + out.Path = in.Path + out.Version = in.Version + return nil +} + +// Convert_dashboard_VersionsQueryOptions_To_v0alpha1_VersionsQueryOptions is an autogenerated conversion function. +func Convert_dashboard_VersionsQueryOptions_To_v0alpha1_VersionsQueryOptions(in *dashboard.VersionsQueryOptions, out *VersionsQueryOptions, s conversion.Scope) error { + return autoConvert_dashboard_VersionsQueryOptions_To_v0alpha1_VersionsQueryOptions(in, out, s) +} + +func autoConvert_url_Values_To_v0alpha1_VersionsQueryOptions(in *url.Values, out *VersionsQueryOptions, s conversion.Scope) error { + // WARNING: Field TypeMeta does not have json tag, skipping. + + if values, ok := map[string][]string(*in)["path"]; ok && len(values) > 0 { + if err := runtime.Convert_Slice_string_To_string(&values, &out.Path, s); err != nil { + return err + } + } else { + out.Path = "" + } + if values, ok := map[string][]string(*in)["version"]; ok && len(values) > 0 { + if err := runtime.Convert_Slice_string_To_int64(&values, &out.Version, s); err != nil { + return err + } + } else { + out.Version = 0 + } + return nil +} + +// Convert_url_Values_To_v0alpha1_VersionsQueryOptions is an autogenerated conversion function. +func Convert_url_Values_To_v0alpha1_VersionsQueryOptions(in *url.Values, out *VersionsQueryOptions, s conversion.Scope) error { + return autoConvert_url_Values_To_v0alpha1_VersionsQueryOptions(in, out, s) +} diff --git a/pkg/apis/dashboard/v1alpha1/conversion.go b/pkg/apis/dashboard/v1alpha1/conversion.go new file mode 100644 index 00000000000..cc512e7c38c --- /dev/null +++ b/pkg/apis/dashboard/v1alpha1/conversion.go @@ -0,0 +1,32 @@ +package v1alpha1 + +import ( + conversion "k8s.io/apimachinery/pkg/conversion" + klog "k8s.io/klog/v2" + + common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" +) + +func Convert_v0alpha1_Unstructured_To_v1alpha1_DashboardSpec(in *common.Unstructured, out *DashboardSpec, s conversion.Scope) error { + out.Unstructured = *in + + t, ok := in.Object["title"] + if !ok { + return nil // skip setting the title if it's not in the unstructured object + } + + title, ok := t.(string) + if !ok { + klog.V(5).Infof("unstructured dashboard title field is not a string %v", t) + return nil // skip setting the title if it's not a string in the unstructured object + } + out.Title = title + + return nil +} + +func Convert_v1alpha1_DashboardSpec_To_v0alpha1_Unstructured(in *DashboardSpec, out *common.Unstructured, s conversion.Scope) error { + *out = in.Unstructured + out.Object["title"] = in.Title + return nil +} diff --git a/pkg/apis/dashboard/v1alpha1/conversion_test.go b/pkg/apis/dashboard/v1alpha1/conversion_test.go new file mode 100644 index 00000000000..dfca8a320ea --- /dev/null +++ b/pkg/apis/dashboard/v1alpha1/conversion_test.go @@ -0,0 +1,65 @@ +package v1alpha1 + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" + + common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" +) + +func TestConvertDashboardVersions(t *testing.T) { + dashboardV0Spec := []byte(`{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations \u0026 Alerts", + "type": "dashboard" + } + ] + }, + "description": "", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 11711, + "links": [], + "panels": [], + "preload": false, + "schemaVersion": 40, + "tags": [], + "templating": { + "list": [] + }, + "timepicker": {}, + "timezone": "utc", + "title": "New dashboard", + "uid": "be3ymutzclgqod", + "version": 1, + "weekStart": "" +}`) + object := common.Unstructured{} + err := json.Unmarshal(dashboardV0Spec, &object.Object) + require.NoError(t, err) + result := DashboardSpec{} + // convert v0 to v1, where we should extract the title & all other elements should be copied + err = Convert_v0alpha1_Unstructured_To_v1alpha1_DashboardSpec(&object, &result, nil) + require.NoError(t, err) + require.Equal(t, result.Title, "New dashboard") + require.Equal(t, result.Unstructured, object) + + // now convert back & ensure it is the same + object2 := common.Unstructured{} + err = Convert_v1alpha1_DashboardSpec_To_v0alpha1_Unstructured(&result, &object2, nil) + require.NoError(t, err) + require.Equal(t, object, object2) +} diff --git a/pkg/apis/dashboard/v1alpha1/doc.go b/pkg/apis/dashboard/v1alpha1/doc.go new file mode 100644 index 00000000000..288a406db14 --- /dev/null +++ b/pkg/apis/dashboard/v1alpha1/doc.go @@ -0,0 +1,7 @@ +// +k8s:deepcopy-gen=package +// +k8s:openapi-gen=true +// +k8s:defaulter-gen=TypeMeta +// +k8s:conversion-gen=github.com/grafana/grafana/pkg/apis/dashboard +// +groupName=dashboard.grafana.app + +package v1alpha1 // import "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1" diff --git a/pkg/apis/dashboard/v1alpha1/register.go b/pkg/apis/dashboard/v1alpha1/register.go new file mode 100644 index 00000000000..1eca26d19a6 --- /dev/null +++ b/pkg/apis/dashboard/v1alpha1/register.go @@ -0,0 +1,103 @@ +package v1alpha1 + +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 = "dashboard.grafana.app" + VERSION = "v1alpha1" + APIVERSION = GROUP + "/" + VERSION +) + +var DashboardResourceInfo = utils.NewResourceInfo(GROUP, VERSION, + "dashboards", "dashboard", "Dashboard", + func() runtime.Object { return &Dashboard{} }, + func() runtime.Object { return &DashboardList{} }, + utils.TableColumns{ + Definition: []metav1.TableColumnDefinition{ + {Name: "Name", Type: "string", Format: "name"}, + {Name: "Title", Type: "string", Format: "string", Description: "The dashboard name"}, + {Name: "Created At", Type: "date"}, + }, + Reader: func(obj any) ([]interface{}, error) { + dash, ok := obj.(*Dashboard) + if ok { + if dash != nil { + return []interface{}{ + dash.Name, + dash.Spec.GetNestedString("title"), + dash.CreationTimestamp.UTC().Format(time.RFC3339), + }, nil + } + } + return nil, fmt.Errorf("expected dashboard") + }, + }, +) + +var LibraryPanelResourceInfo = utils.NewResourceInfo(GROUP, VERSION, + "librarypanels", "librarypanel", "LibraryPanel", + func() runtime.Object { return &LibraryPanel{} }, + func() runtime.Object { return &LibraryPanelList{} }, + utils.TableColumns{ + Definition: []metav1.TableColumnDefinition{ + {Name: "Name", Type: "string", Format: "name"}, + {Name: "Title", Type: "string", Description: "The dashboard name"}, + {Name: "Type", Type: "string", Description: "the panel type"}, + {Name: "Created At", Type: "date"}, + }, + Reader: func(obj any) ([]interface{}, error) { + dash, ok := obj.(*LibraryPanel) + if ok { + if dash != nil { + return []interface{}{ + dash.Name, + dash.Spec.Title, + dash.Spec.Type, + dash.CreationTimestamp.UTC().Format(time.RFC3339), + }, nil + } + } + return nil, fmt.Errorf("expected library panel") + }, + }, +) + +var ( + SchemeBuilder runtime.SchemeBuilder + localSchemeBuilder = &SchemeBuilder + AddToScheme = localSchemeBuilder.AddToScheme + schemeGroupVersion = schema.GroupVersion{Group: GROUP, Version: VERSION} +) + +func init() { + localSchemeBuilder.Register(addKnownTypes, addDefaultingFuncs) +} + +// Adds the list of known types to the given scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(schemeGroupVersion, + &Dashboard{}, + &DashboardList{}, + &DashboardWithAccessInfo{}, + &DashboardVersionList{}, + &VersionsQueryOptions{}, + &LibraryPanel{}, + &LibraryPanelList{}, + &metav1.PartialObjectMetadata{}, + &metav1.PartialObjectMetadataList{}, + ) + metav1.AddToGroupVersion(scheme, schemeGroupVersion) + return nil +} + +func addDefaultingFuncs(scheme *runtime.Scheme) error { + return RegisterDefaults(scheme) +} diff --git a/pkg/apis/dashboard/v1alpha1/types.go b/pkg/apis/dashboard/v1alpha1/types.go new file mode 100644 index 00000000000..e563b4ea85d --- /dev/null +++ b/pkg/apis/dashboard/v1alpha1/types.go @@ -0,0 +1,166 @@ +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + data "github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1" + common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type Dashboard struct { + metav1.TypeMeta `json:",inline"` + // Standard object's metadata + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // The dashboard body (unstructured for now) + Spec DashboardSpec `json:"spec"` +} + +type DashboardSpec struct { + Title string `json:"title"` + common.Unstructured `json:",inline"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type DashboardList struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ListMeta `json:"metadata,omitempty"` + + Items []Dashboard `json:"items,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type DashboardVersionList struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ListMeta `json:"metadata,omitempty"` + + Items []DashboardVersionInfo `json:"items,omitempty"` +} + +type DashboardVersionInfo struct { + // The internal ID for this version (will be replaced with resourceVersion) + Version int `json:"version"` + + // If the dashboard came from a previous version, it is set here + ParentVersion int `json:"parentVersion,omitempty"` + + // The creation timestamp for this version + Created int64 `json:"created"` + + // The user who created this version + CreatedBy string `json:"createdBy,omitempty"` + + // Message passed while saving the version + Message string `json:"message,omitempty"` +} + +// +k8s:conversion-gen:explicit-from=net/url.Values +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type VersionsQueryOptions struct { + metav1.TypeMeta `json:",inline"` + + // Path is the URL path + // +optional + Path string `json:"path,omitempty"` + + // +optional + Version int64 `json:"version,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type LibraryPanel struct { + metav1.TypeMeta `json:",inline"` + // Standard object's metadata + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Panel properties + Spec LibraryPanelSpec `json:"spec"` + + // Status will show errors + Status *LibraryPanelStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type LibraryPanelList struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ListMeta `json:"metadata,omitempty"` + + Items []LibraryPanel `json:"items,omitempty"` +} + +type LibraryPanelSpec struct { + // The panel type + Type string `json:"type"` + + // The panel type + PluginVersion string `json:"pluginVersion,omitempty"` + + // The panel title + Title string `json:"title,omitempty"` + + // Library panel description + Description string `json:"description,omitempty"` + + // The options schema depends on the panel type + Options common.Unstructured `json:"options"` + + // The fieldConfig schema depends on the panel type + FieldConfig common.Unstructured `json:"fieldConfig"` + + // The default datasource type + Datasource *data.DataSourceRef `json:"datasource,omitempty"` + + // The datasource queries + // +listType=set + Targets []data.DataQuery `json:"targets,omitempty"` +} + +type LibraryPanelStatus struct { + // Translation warnings (mostly things that were in SQL columns but not found in the saved body) + Warnings []string `json:"warnings,omitempty"` + + // The properties previously stored in SQL that are not included in this model + Missing common.Unstructured `json:"missing,omitempty"` +} + +// This is like the legacy DTO where access and metadata are all returned in a single call +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type DashboardWithAccessInfo struct { + Dashboard `json:",inline"` + + Access DashboardAccess `json:"access"` +} + +// Information about how the requesting user can use a given dashboard +type DashboardAccess struct { + // Metadata fields + Slug string `json:"slug,omitempty"` + Url string `json:"url,omitempty"` + + // The permissions part + CanSave bool `json:"canSave"` + CanEdit bool `json:"canEdit"` + CanAdmin bool `json:"canAdmin"` + CanStar bool `json:"canStar"` + CanDelete bool `json:"canDelete"` + AnnotationsPermissions *AnnotationPermission `json:"annotationsPermissions"` +} + +type AnnotationPermission struct { + Dashboard AnnotationActions `json:"dashboard"` + Organization AnnotationActions `json:"organization"` +} + +type AnnotationActions struct { + CanAdd bool `json:"canAdd"` + CanEdit bool `json:"canEdit"` + CanDelete bool `json:"canDelete"` +} diff --git a/pkg/apis/dashboard/v1alpha1/zz_generated.conversion.go b/pkg/apis/dashboard/v1alpha1/zz_generated.conversion.go new file mode 100644 index 00000000000..fb0b12800df --- /dev/null +++ b/pkg/apis/dashboard/v1alpha1/zz_generated.conversion.go @@ -0,0 +1,563 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// SPDX-License-Identifier: AGPL-3.0-only + +// Code generated by conversion-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + url "net/url" + unsafe "unsafe" + + datav0alpha1 "github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1" + v0alpha1 "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" + dashboard "github.com/grafana/grafana/pkg/apis/dashboard" + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*AnnotationActions)(nil), (*dashboard.AnnotationActions)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_AnnotationActions_To_dashboard_AnnotationActions(a.(*AnnotationActions), b.(*dashboard.AnnotationActions), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.AnnotationActions)(nil), (*AnnotationActions)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_AnnotationActions_To_v1alpha1_AnnotationActions(a.(*dashboard.AnnotationActions), b.(*AnnotationActions), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*AnnotationPermission)(nil), (*dashboard.AnnotationPermission)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_AnnotationPermission_To_dashboard_AnnotationPermission(a.(*AnnotationPermission), b.(*dashboard.AnnotationPermission), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.AnnotationPermission)(nil), (*AnnotationPermission)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_AnnotationPermission_To_v1alpha1_AnnotationPermission(a.(*dashboard.AnnotationPermission), b.(*AnnotationPermission), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*Dashboard)(nil), (*dashboard.Dashboard)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_Dashboard_To_dashboard_Dashboard(a.(*Dashboard), b.(*dashboard.Dashboard), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.Dashboard)(nil), (*Dashboard)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_Dashboard_To_v1alpha1_Dashboard(a.(*dashboard.Dashboard), b.(*Dashboard), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DashboardAccess)(nil), (*dashboard.DashboardAccess)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_DashboardAccess_To_dashboard_DashboardAccess(a.(*DashboardAccess), b.(*dashboard.DashboardAccess), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.DashboardAccess)(nil), (*DashboardAccess)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_DashboardAccess_To_v1alpha1_DashboardAccess(a.(*dashboard.DashboardAccess), b.(*DashboardAccess), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DashboardList)(nil), (*dashboard.DashboardList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_DashboardList_To_dashboard_DashboardList(a.(*DashboardList), b.(*dashboard.DashboardList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.DashboardList)(nil), (*DashboardList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_DashboardList_To_v1alpha1_DashboardList(a.(*dashboard.DashboardList), b.(*DashboardList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DashboardVersionInfo)(nil), (*dashboard.DashboardVersionInfo)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_DashboardVersionInfo_To_dashboard_DashboardVersionInfo(a.(*DashboardVersionInfo), b.(*dashboard.DashboardVersionInfo), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.DashboardVersionInfo)(nil), (*DashboardVersionInfo)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_DashboardVersionInfo_To_v1alpha1_DashboardVersionInfo(a.(*dashboard.DashboardVersionInfo), b.(*DashboardVersionInfo), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DashboardVersionList)(nil), (*dashboard.DashboardVersionList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_DashboardVersionList_To_dashboard_DashboardVersionList(a.(*DashboardVersionList), b.(*dashboard.DashboardVersionList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.DashboardVersionList)(nil), (*DashboardVersionList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_DashboardVersionList_To_v1alpha1_DashboardVersionList(a.(*dashboard.DashboardVersionList), b.(*DashboardVersionList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DashboardWithAccessInfo)(nil), (*dashboard.DashboardWithAccessInfo)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_DashboardWithAccessInfo_To_dashboard_DashboardWithAccessInfo(a.(*DashboardWithAccessInfo), b.(*dashboard.DashboardWithAccessInfo), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.DashboardWithAccessInfo)(nil), (*DashboardWithAccessInfo)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_DashboardWithAccessInfo_To_v1alpha1_DashboardWithAccessInfo(a.(*dashboard.DashboardWithAccessInfo), b.(*DashboardWithAccessInfo), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*LibraryPanel)(nil), (*dashboard.LibraryPanel)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_LibraryPanel_To_dashboard_LibraryPanel(a.(*LibraryPanel), b.(*dashboard.LibraryPanel), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.LibraryPanel)(nil), (*LibraryPanel)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_LibraryPanel_To_v1alpha1_LibraryPanel(a.(*dashboard.LibraryPanel), b.(*LibraryPanel), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*LibraryPanelList)(nil), (*dashboard.LibraryPanelList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_LibraryPanelList_To_dashboard_LibraryPanelList(a.(*LibraryPanelList), b.(*dashboard.LibraryPanelList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.LibraryPanelList)(nil), (*LibraryPanelList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_LibraryPanelList_To_v1alpha1_LibraryPanelList(a.(*dashboard.LibraryPanelList), b.(*LibraryPanelList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*LibraryPanelSpec)(nil), (*dashboard.LibraryPanelSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_LibraryPanelSpec_To_dashboard_LibraryPanelSpec(a.(*LibraryPanelSpec), b.(*dashboard.LibraryPanelSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.LibraryPanelSpec)(nil), (*LibraryPanelSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_LibraryPanelSpec_To_v1alpha1_LibraryPanelSpec(a.(*dashboard.LibraryPanelSpec), b.(*LibraryPanelSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*LibraryPanelStatus)(nil), (*dashboard.LibraryPanelStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_LibraryPanelStatus_To_dashboard_LibraryPanelStatus(a.(*LibraryPanelStatus), b.(*dashboard.LibraryPanelStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.LibraryPanelStatus)(nil), (*LibraryPanelStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_LibraryPanelStatus_To_v1alpha1_LibraryPanelStatus(a.(*dashboard.LibraryPanelStatus), b.(*LibraryPanelStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*VersionsQueryOptions)(nil), (*dashboard.VersionsQueryOptions)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_VersionsQueryOptions_To_dashboard_VersionsQueryOptions(a.(*VersionsQueryOptions), b.(*dashboard.VersionsQueryOptions), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.VersionsQueryOptions)(nil), (*VersionsQueryOptions)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_VersionsQueryOptions_To_v1alpha1_VersionsQueryOptions(a.(*dashboard.VersionsQueryOptions), b.(*VersionsQueryOptions), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*url.Values)(nil), (*VersionsQueryOptions)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_url_Values_To_v1alpha1_VersionsQueryOptions(a.(*url.Values), b.(*VersionsQueryOptions), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v0alpha1.Unstructured)(nil), (*DashboardSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v0alpha1_Unstructured_To_v1alpha1_DashboardSpec(a.(*v0alpha1.Unstructured), b.(*DashboardSpec), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*DashboardSpec)(nil), (*v0alpha1.Unstructured)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_DashboardSpec_To_v0alpha1_Unstructured(a.(*DashboardSpec), b.(*v0alpha1.Unstructured), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha1_AnnotationActions_To_dashboard_AnnotationActions(in *AnnotationActions, out *dashboard.AnnotationActions, s conversion.Scope) error { + out.CanAdd = in.CanAdd + out.CanEdit = in.CanEdit + out.CanDelete = in.CanDelete + return nil +} + +// Convert_v1alpha1_AnnotationActions_To_dashboard_AnnotationActions is an autogenerated conversion function. +func Convert_v1alpha1_AnnotationActions_To_dashboard_AnnotationActions(in *AnnotationActions, out *dashboard.AnnotationActions, s conversion.Scope) error { + return autoConvert_v1alpha1_AnnotationActions_To_dashboard_AnnotationActions(in, out, s) +} + +func autoConvert_dashboard_AnnotationActions_To_v1alpha1_AnnotationActions(in *dashboard.AnnotationActions, out *AnnotationActions, s conversion.Scope) error { + out.CanAdd = in.CanAdd + out.CanEdit = in.CanEdit + out.CanDelete = in.CanDelete + return nil +} + +// Convert_dashboard_AnnotationActions_To_v1alpha1_AnnotationActions is an autogenerated conversion function. +func Convert_dashboard_AnnotationActions_To_v1alpha1_AnnotationActions(in *dashboard.AnnotationActions, out *AnnotationActions, s conversion.Scope) error { + return autoConvert_dashboard_AnnotationActions_To_v1alpha1_AnnotationActions(in, out, s) +} + +func autoConvert_v1alpha1_AnnotationPermission_To_dashboard_AnnotationPermission(in *AnnotationPermission, out *dashboard.AnnotationPermission, s conversion.Scope) error { + if err := Convert_v1alpha1_AnnotationActions_To_dashboard_AnnotationActions(&in.Dashboard, &out.Dashboard, s); err != nil { + return err + } + if err := Convert_v1alpha1_AnnotationActions_To_dashboard_AnnotationActions(&in.Organization, &out.Organization, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha1_AnnotationPermission_To_dashboard_AnnotationPermission is an autogenerated conversion function. +func Convert_v1alpha1_AnnotationPermission_To_dashboard_AnnotationPermission(in *AnnotationPermission, out *dashboard.AnnotationPermission, s conversion.Scope) error { + return autoConvert_v1alpha1_AnnotationPermission_To_dashboard_AnnotationPermission(in, out, s) +} + +func autoConvert_dashboard_AnnotationPermission_To_v1alpha1_AnnotationPermission(in *dashboard.AnnotationPermission, out *AnnotationPermission, s conversion.Scope) error { + if err := Convert_dashboard_AnnotationActions_To_v1alpha1_AnnotationActions(&in.Dashboard, &out.Dashboard, s); err != nil { + return err + } + if err := Convert_dashboard_AnnotationActions_To_v1alpha1_AnnotationActions(&in.Organization, &out.Organization, s); err != nil { + return err + } + return nil +} + +// Convert_dashboard_AnnotationPermission_To_v1alpha1_AnnotationPermission is an autogenerated conversion function. +func Convert_dashboard_AnnotationPermission_To_v1alpha1_AnnotationPermission(in *dashboard.AnnotationPermission, out *AnnotationPermission, s conversion.Scope) error { + return autoConvert_dashboard_AnnotationPermission_To_v1alpha1_AnnotationPermission(in, out, s) +} + +func autoConvert_v1alpha1_Dashboard_To_dashboard_Dashboard(in *Dashboard, out *dashboard.Dashboard, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha1_DashboardSpec_To_v0alpha1_Unstructured(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha1_Dashboard_To_dashboard_Dashboard is an autogenerated conversion function. +func Convert_v1alpha1_Dashboard_To_dashboard_Dashboard(in *Dashboard, out *dashboard.Dashboard, s conversion.Scope) error { + return autoConvert_v1alpha1_Dashboard_To_dashboard_Dashboard(in, out, s) +} + +func autoConvert_dashboard_Dashboard_To_v1alpha1_Dashboard(in *dashboard.Dashboard, out *Dashboard, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v0alpha1_Unstructured_To_v1alpha1_DashboardSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +// Convert_dashboard_Dashboard_To_v1alpha1_Dashboard is an autogenerated conversion function. +func Convert_dashboard_Dashboard_To_v1alpha1_Dashboard(in *dashboard.Dashboard, out *Dashboard, s conversion.Scope) error { + return autoConvert_dashboard_Dashboard_To_v1alpha1_Dashboard(in, out, s) +} + +func autoConvert_v1alpha1_DashboardAccess_To_dashboard_DashboardAccess(in *DashboardAccess, out *dashboard.DashboardAccess, s conversion.Scope) error { + out.Slug = in.Slug + out.Url = in.Url + out.CanSave = in.CanSave + out.CanEdit = in.CanEdit + out.CanAdmin = in.CanAdmin + out.CanStar = in.CanStar + out.CanDelete = in.CanDelete + out.AnnotationsPermissions = (*dashboard.AnnotationPermission)(unsafe.Pointer(in.AnnotationsPermissions)) + return nil +} + +// Convert_v1alpha1_DashboardAccess_To_dashboard_DashboardAccess is an autogenerated conversion function. +func Convert_v1alpha1_DashboardAccess_To_dashboard_DashboardAccess(in *DashboardAccess, out *dashboard.DashboardAccess, s conversion.Scope) error { + return autoConvert_v1alpha1_DashboardAccess_To_dashboard_DashboardAccess(in, out, s) +} + +func autoConvert_dashboard_DashboardAccess_To_v1alpha1_DashboardAccess(in *dashboard.DashboardAccess, out *DashboardAccess, s conversion.Scope) error { + out.Slug = in.Slug + out.Url = in.Url + out.CanSave = in.CanSave + out.CanEdit = in.CanEdit + out.CanAdmin = in.CanAdmin + out.CanStar = in.CanStar + out.CanDelete = in.CanDelete + out.AnnotationsPermissions = (*AnnotationPermission)(unsafe.Pointer(in.AnnotationsPermissions)) + return nil +} + +// Convert_dashboard_DashboardAccess_To_v1alpha1_DashboardAccess is an autogenerated conversion function. +func Convert_dashboard_DashboardAccess_To_v1alpha1_DashboardAccess(in *dashboard.DashboardAccess, out *DashboardAccess, s conversion.Scope) error { + return autoConvert_dashboard_DashboardAccess_To_v1alpha1_DashboardAccess(in, out, s) +} + +func autoConvert_v1alpha1_DashboardList_To_dashboard_DashboardList(in *DashboardList, out *dashboard.DashboardList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]dashboard.Dashboard, len(*in)) + for i := range *in { + if err := Convert_v1alpha1_Dashboard_To_dashboard_Dashboard(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1alpha1_DashboardList_To_dashboard_DashboardList is an autogenerated conversion function. +func Convert_v1alpha1_DashboardList_To_dashboard_DashboardList(in *DashboardList, out *dashboard.DashboardList, s conversion.Scope) error { + return autoConvert_v1alpha1_DashboardList_To_dashboard_DashboardList(in, out, s) +} + +func autoConvert_dashboard_DashboardList_To_v1alpha1_DashboardList(in *dashboard.DashboardList, out *DashboardList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Dashboard, len(*in)) + for i := range *in { + if err := Convert_dashboard_Dashboard_To_v1alpha1_Dashboard(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_dashboard_DashboardList_To_v1alpha1_DashboardList is an autogenerated conversion function. +func Convert_dashboard_DashboardList_To_v1alpha1_DashboardList(in *dashboard.DashboardList, out *DashboardList, s conversion.Scope) error { + return autoConvert_dashboard_DashboardList_To_v1alpha1_DashboardList(in, out, s) +} + +func autoConvert_v1alpha1_DashboardVersionInfo_To_dashboard_DashboardVersionInfo(in *DashboardVersionInfo, out *dashboard.DashboardVersionInfo, s conversion.Scope) error { + out.Version = in.Version + out.ParentVersion = in.ParentVersion + out.Created = in.Created + out.CreatedBy = in.CreatedBy + out.Message = in.Message + return nil +} + +// Convert_v1alpha1_DashboardVersionInfo_To_dashboard_DashboardVersionInfo is an autogenerated conversion function. +func Convert_v1alpha1_DashboardVersionInfo_To_dashboard_DashboardVersionInfo(in *DashboardVersionInfo, out *dashboard.DashboardVersionInfo, s conversion.Scope) error { + return autoConvert_v1alpha1_DashboardVersionInfo_To_dashboard_DashboardVersionInfo(in, out, s) +} + +func autoConvert_dashboard_DashboardVersionInfo_To_v1alpha1_DashboardVersionInfo(in *dashboard.DashboardVersionInfo, out *DashboardVersionInfo, s conversion.Scope) error { + out.Version = in.Version + out.ParentVersion = in.ParentVersion + out.Created = in.Created + out.CreatedBy = in.CreatedBy + out.Message = in.Message + return nil +} + +// Convert_dashboard_DashboardVersionInfo_To_v1alpha1_DashboardVersionInfo is an autogenerated conversion function. +func Convert_dashboard_DashboardVersionInfo_To_v1alpha1_DashboardVersionInfo(in *dashboard.DashboardVersionInfo, out *DashboardVersionInfo, s conversion.Scope) error { + return autoConvert_dashboard_DashboardVersionInfo_To_v1alpha1_DashboardVersionInfo(in, out, s) +} + +func autoConvert_v1alpha1_DashboardVersionList_To_dashboard_DashboardVersionList(in *DashboardVersionList, out *dashboard.DashboardVersionList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]dashboard.DashboardVersionInfo)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_v1alpha1_DashboardVersionList_To_dashboard_DashboardVersionList is an autogenerated conversion function. +func Convert_v1alpha1_DashboardVersionList_To_dashboard_DashboardVersionList(in *DashboardVersionList, out *dashboard.DashboardVersionList, s conversion.Scope) error { + return autoConvert_v1alpha1_DashboardVersionList_To_dashboard_DashboardVersionList(in, out, s) +} + +func autoConvert_dashboard_DashboardVersionList_To_v1alpha1_DashboardVersionList(in *dashboard.DashboardVersionList, out *DashboardVersionList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]DashboardVersionInfo)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_dashboard_DashboardVersionList_To_v1alpha1_DashboardVersionList is an autogenerated conversion function. +func Convert_dashboard_DashboardVersionList_To_v1alpha1_DashboardVersionList(in *dashboard.DashboardVersionList, out *DashboardVersionList, s conversion.Scope) error { + return autoConvert_dashboard_DashboardVersionList_To_v1alpha1_DashboardVersionList(in, out, s) +} + +func autoConvert_v1alpha1_DashboardWithAccessInfo_To_dashboard_DashboardWithAccessInfo(in *DashboardWithAccessInfo, out *dashboard.DashboardWithAccessInfo, s conversion.Scope) error { + if err := Convert_v1alpha1_Dashboard_To_dashboard_Dashboard(&in.Dashboard, &out.Dashboard, s); err != nil { + return err + } + if err := Convert_v1alpha1_DashboardAccess_To_dashboard_DashboardAccess(&in.Access, &out.Access, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha1_DashboardWithAccessInfo_To_dashboard_DashboardWithAccessInfo is an autogenerated conversion function. +func Convert_v1alpha1_DashboardWithAccessInfo_To_dashboard_DashboardWithAccessInfo(in *DashboardWithAccessInfo, out *dashboard.DashboardWithAccessInfo, s conversion.Scope) error { + return autoConvert_v1alpha1_DashboardWithAccessInfo_To_dashboard_DashboardWithAccessInfo(in, out, s) +} + +func autoConvert_dashboard_DashboardWithAccessInfo_To_v1alpha1_DashboardWithAccessInfo(in *dashboard.DashboardWithAccessInfo, out *DashboardWithAccessInfo, s conversion.Scope) error { + if err := Convert_dashboard_Dashboard_To_v1alpha1_Dashboard(&in.Dashboard, &out.Dashboard, s); err != nil { + return err + } + if err := Convert_dashboard_DashboardAccess_To_v1alpha1_DashboardAccess(&in.Access, &out.Access, s); err != nil { + return err + } + return nil +} + +// Convert_dashboard_DashboardWithAccessInfo_To_v1alpha1_DashboardWithAccessInfo is an autogenerated conversion function. +func Convert_dashboard_DashboardWithAccessInfo_To_v1alpha1_DashboardWithAccessInfo(in *dashboard.DashboardWithAccessInfo, out *DashboardWithAccessInfo, s conversion.Scope) error { + return autoConvert_dashboard_DashboardWithAccessInfo_To_v1alpha1_DashboardWithAccessInfo(in, out, s) +} + +func autoConvert_v1alpha1_LibraryPanel_To_dashboard_LibraryPanel(in *LibraryPanel, out *dashboard.LibraryPanel, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha1_LibraryPanelSpec_To_dashboard_LibraryPanelSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + out.Status = (*dashboard.LibraryPanelStatus)(unsafe.Pointer(in.Status)) + return nil +} + +// Convert_v1alpha1_LibraryPanel_To_dashboard_LibraryPanel is an autogenerated conversion function. +func Convert_v1alpha1_LibraryPanel_To_dashboard_LibraryPanel(in *LibraryPanel, out *dashboard.LibraryPanel, s conversion.Scope) error { + return autoConvert_v1alpha1_LibraryPanel_To_dashboard_LibraryPanel(in, out, s) +} + +func autoConvert_dashboard_LibraryPanel_To_v1alpha1_LibraryPanel(in *dashboard.LibraryPanel, out *LibraryPanel, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_dashboard_LibraryPanelSpec_To_v1alpha1_LibraryPanelSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + out.Status = (*LibraryPanelStatus)(unsafe.Pointer(in.Status)) + return nil +} + +// Convert_dashboard_LibraryPanel_To_v1alpha1_LibraryPanel is an autogenerated conversion function. +func Convert_dashboard_LibraryPanel_To_v1alpha1_LibraryPanel(in *dashboard.LibraryPanel, out *LibraryPanel, s conversion.Scope) error { + return autoConvert_dashboard_LibraryPanel_To_v1alpha1_LibraryPanel(in, out, s) +} + +func autoConvert_v1alpha1_LibraryPanelList_To_dashboard_LibraryPanelList(in *LibraryPanelList, out *dashboard.LibraryPanelList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]dashboard.LibraryPanel)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_v1alpha1_LibraryPanelList_To_dashboard_LibraryPanelList is an autogenerated conversion function. +func Convert_v1alpha1_LibraryPanelList_To_dashboard_LibraryPanelList(in *LibraryPanelList, out *dashboard.LibraryPanelList, s conversion.Scope) error { + return autoConvert_v1alpha1_LibraryPanelList_To_dashboard_LibraryPanelList(in, out, s) +} + +func autoConvert_dashboard_LibraryPanelList_To_v1alpha1_LibraryPanelList(in *dashboard.LibraryPanelList, out *LibraryPanelList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]LibraryPanel)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_dashboard_LibraryPanelList_To_v1alpha1_LibraryPanelList is an autogenerated conversion function. +func Convert_dashboard_LibraryPanelList_To_v1alpha1_LibraryPanelList(in *dashboard.LibraryPanelList, out *LibraryPanelList, s conversion.Scope) error { + return autoConvert_dashboard_LibraryPanelList_To_v1alpha1_LibraryPanelList(in, out, s) +} + +func autoConvert_v1alpha1_LibraryPanelSpec_To_dashboard_LibraryPanelSpec(in *LibraryPanelSpec, out *dashboard.LibraryPanelSpec, s conversion.Scope) error { + out.Type = in.Type + out.PluginVersion = in.PluginVersion + out.Title = in.Title + out.Description = in.Description + out.Options = in.Options + out.FieldConfig = in.FieldConfig + out.Datasource = (*datav0alpha1.DataSourceRef)(unsafe.Pointer(in.Datasource)) + out.Targets = *(*[]datav0alpha1.DataQuery)(unsafe.Pointer(&in.Targets)) + return nil +} + +// Convert_v1alpha1_LibraryPanelSpec_To_dashboard_LibraryPanelSpec is an autogenerated conversion function. +func Convert_v1alpha1_LibraryPanelSpec_To_dashboard_LibraryPanelSpec(in *LibraryPanelSpec, out *dashboard.LibraryPanelSpec, s conversion.Scope) error { + return autoConvert_v1alpha1_LibraryPanelSpec_To_dashboard_LibraryPanelSpec(in, out, s) +} + +func autoConvert_dashboard_LibraryPanelSpec_To_v1alpha1_LibraryPanelSpec(in *dashboard.LibraryPanelSpec, out *LibraryPanelSpec, s conversion.Scope) error { + out.Type = in.Type + out.PluginVersion = in.PluginVersion + out.Title = in.Title + out.Description = in.Description + out.Options = in.Options + out.FieldConfig = in.FieldConfig + out.Datasource = (*datav0alpha1.DataSourceRef)(unsafe.Pointer(in.Datasource)) + out.Targets = *(*[]datav0alpha1.DataQuery)(unsafe.Pointer(&in.Targets)) + return nil +} + +// Convert_dashboard_LibraryPanelSpec_To_v1alpha1_LibraryPanelSpec is an autogenerated conversion function. +func Convert_dashboard_LibraryPanelSpec_To_v1alpha1_LibraryPanelSpec(in *dashboard.LibraryPanelSpec, out *LibraryPanelSpec, s conversion.Scope) error { + return autoConvert_dashboard_LibraryPanelSpec_To_v1alpha1_LibraryPanelSpec(in, out, s) +} + +func autoConvert_v1alpha1_LibraryPanelStatus_To_dashboard_LibraryPanelStatus(in *LibraryPanelStatus, out *dashboard.LibraryPanelStatus, s conversion.Scope) error { + out.Warnings = *(*[]string)(unsafe.Pointer(&in.Warnings)) + out.Missing = in.Missing + return nil +} + +// Convert_v1alpha1_LibraryPanelStatus_To_dashboard_LibraryPanelStatus is an autogenerated conversion function. +func Convert_v1alpha1_LibraryPanelStatus_To_dashboard_LibraryPanelStatus(in *LibraryPanelStatus, out *dashboard.LibraryPanelStatus, s conversion.Scope) error { + return autoConvert_v1alpha1_LibraryPanelStatus_To_dashboard_LibraryPanelStatus(in, out, s) +} + +func autoConvert_dashboard_LibraryPanelStatus_To_v1alpha1_LibraryPanelStatus(in *dashboard.LibraryPanelStatus, out *LibraryPanelStatus, s conversion.Scope) error { + out.Warnings = *(*[]string)(unsafe.Pointer(&in.Warnings)) + out.Missing = in.Missing + return nil +} + +// Convert_dashboard_LibraryPanelStatus_To_v1alpha1_LibraryPanelStatus is an autogenerated conversion function. +func Convert_dashboard_LibraryPanelStatus_To_v1alpha1_LibraryPanelStatus(in *dashboard.LibraryPanelStatus, out *LibraryPanelStatus, s conversion.Scope) error { + return autoConvert_dashboard_LibraryPanelStatus_To_v1alpha1_LibraryPanelStatus(in, out, s) +} + +func autoConvert_v1alpha1_VersionsQueryOptions_To_dashboard_VersionsQueryOptions(in *VersionsQueryOptions, out *dashboard.VersionsQueryOptions, s conversion.Scope) error { + out.Path = in.Path + out.Version = in.Version + return nil +} + +// Convert_v1alpha1_VersionsQueryOptions_To_dashboard_VersionsQueryOptions is an autogenerated conversion function. +func Convert_v1alpha1_VersionsQueryOptions_To_dashboard_VersionsQueryOptions(in *VersionsQueryOptions, out *dashboard.VersionsQueryOptions, s conversion.Scope) error { + return autoConvert_v1alpha1_VersionsQueryOptions_To_dashboard_VersionsQueryOptions(in, out, s) +} + +func autoConvert_dashboard_VersionsQueryOptions_To_v1alpha1_VersionsQueryOptions(in *dashboard.VersionsQueryOptions, out *VersionsQueryOptions, s conversion.Scope) error { + out.Path = in.Path + out.Version = in.Version + return nil +} + +// Convert_dashboard_VersionsQueryOptions_To_v1alpha1_VersionsQueryOptions is an autogenerated conversion function. +func Convert_dashboard_VersionsQueryOptions_To_v1alpha1_VersionsQueryOptions(in *dashboard.VersionsQueryOptions, out *VersionsQueryOptions, s conversion.Scope) error { + return autoConvert_dashboard_VersionsQueryOptions_To_v1alpha1_VersionsQueryOptions(in, out, s) +} + +func autoConvert_url_Values_To_v1alpha1_VersionsQueryOptions(in *url.Values, out *VersionsQueryOptions, s conversion.Scope) error { + // WARNING: Field TypeMeta does not have json tag, skipping. + + if values, ok := map[string][]string(*in)["path"]; ok && len(values) > 0 { + if err := runtime.Convert_Slice_string_To_string(&values, &out.Path, s); err != nil { + return err + } + } else { + out.Path = "" + } + if values, ok := map[string][]string(*in)["version"]; ok && len(values) > 0 { + if err := runtime.Convert_Slice_string_To_int64(&values, &out.Version, s); err != nil { + return err + } + } else { + out.Version = 0 + } + return nil +} + +// Convert_url_Values_To_v1alpha1_VersionsQueryOptions is an autogenerated conversion function. +func Convert_url_Values_To_v1alpha1_VersionsQueryOptions(in *url.Values, out *VersionsQueryOptions, s conversion.Scope) error { + return autoConvert_url_Values_To_v1alpha1_VersionsQueryOptions(in, out, s) +} diff --git a/pkg/apis/dashboard/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/dashboard/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..e47d0bdc25e --- /dev/null +++ b/pkg/apis/dashboard/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,360 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// SPDX-License-Identifier: AGPL-3.0-only + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v0alpha1 "github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1" + 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 *AnnotationActions) DeepCopyInto(out *AnnotationActions) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnnotationActions. +func (in *AnnotationActions) DeepCopy() *AnnotationActions { + if in == nil { + return nil + } + out := new(AnnotationActions) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AnnotationPermission) DeepCopyInto(out *AnnotationPermission) { + *out = *in + out.Dashboard = in.Dashboard + out.Organization = in.Organization + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnnotationPermission. +func (in *AnnotationPermission) DeepCopy() *AnnotationPermission { + if in == nil { + return nil + } + out := new(AnnotationPermission) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Dashboard) DeepCopyInto(out *Dashboard) { + *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 Dashboard. +func (in *Dashboard) DeepCopy() *Dashboard { + if in == nil { + return nil + } + out := new(Dashboard) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Dashboard) 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 *DashboardAccess) DeepCopyInto(out *DashboardAccess) { + *out = *in + if in.AnnotationsPermissions != nil { + in, out := &in.AnnotationsPermissions, &out.AnnotationsPermissions + *out = new(AnnotationPermission) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardAccess. +func (in *DashboardAccess) DeepCopy() *DashboardAccess { + if in == nil { + return nil + } + out := new(DashboardAccess) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DashboardList) DeepCopyInto(out *DashboardList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Dashboard, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardList. +func (in *DashboardList) DeepCopy() *DashboardList { + if in == nil { + return nil + } + out := new(DashboardList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DashboardList) 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 *DashboardSpec) DeepCopyInto(out *DashboardSpec) { + *out = *in + in.Unstructured.DeepCopyInto(&out.Unstructured) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardSpec. +func (in *DashboardSpec) DeepCopy() *DashboardSpec { + if in == nil { + return nil + } + out := new(DashboardSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DashboardVersionInfo) DeepCopyInto(out *DashboardVersionInfo) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardVersionInfo. +func (in *DashboardVersionInfo) DeepCopy() *DashboardVersionInfo { + if in == nil { + return nil + } + out := new(DashboardVersionInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DashboardVersionList) DeepCopyInto(out *DashboardVersionList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]DashboardVersionInfo, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardVersionList. +func (in *DashboardVersionList) DeepCopy() *DashboardVersionList { + if in == nil { + return nil + } + out := new(DashboardVersionList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DashboardVersionList) 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 *DashboardWithAccessInfo) DeepCopyInto(out *DashboardWithAccessInfo) { + *out = *in + in.Dashboard.DeepCopyInto(&out.Dashboard) + in.Access.DeepCopyInto(&out.Access) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardWithAccessInfo. +func (in *DashboardWithAccessInfo) DeepCopy() *DashboardWithAccessInfo { + if in == nil { + return nil + } + out := new(DashboardWithAccessInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DashboardWithAccessInfo) 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 *LibraryPanel) DeepCopyInto(out *LibraryPanel) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + if in.Status != nil { + in, out := &in.Status, &out.Status + *out = new(LibraryPanelStatus) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LibraryPanel. +func (in *LibraryPanel) DeepCopy() *LibraryPanel { + if in == nil { + return nil + } + out := new(LibraryPanel) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *LibraryPanel) 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 *LibraryPanelList) DeepCopyInto(out *LibraryPanelList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]LibraryPanel, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LibraryPanelList. +func (in *LibraryPanelList) DeepCopy() *LibraryPanelList { + if in == nil { + return nil + } + out := new(LibraryPanelList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *LibraryPanelList) 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 *LibraryPanelSpec) DeepCopyInto(out *LibraryPanelSpec) { + *out = *in + in.Options.DeepCopyInto(&out.Options) + in.FieldConfig.DeepCopyInto(&out.FieldConfig) + if in.Datasource != nil { + in, out := &in.Datasource, &out.Datasource + *out = new(v0alpha1.DataSourceRef) + **out = **in + } + if in.Targets != nil { + in, out := &in.Targets, &out.Targets + *out = make([]v0alpha1.DataQuery, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LibraryPanelSpec. +func (in *LibraryPanelSpec) DeepCopy() *LibraryPanelSpec { + if in == nil { + return nil + } + out := new(LibraryPanelSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LibraryPanelStatus) DeepCopyInto(out *LibraryPanelStatus) { + *out = *in + if in.Warnings != nil { + in, out := &in.Warnings, &out.Warnings + *out = make([]string, len(*in)) + copy(*out, *in) + } + in.Missing.DeepCopyInto(&out.Missing) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LibraryPanelStatus. +func (in *LibraryPanelStatus) DeepCopy() *LibraryPanelStatus { + if in == nil { + return nil + } + out := new(LibraryPanelStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VersionsQueryOptions) DeepCopyInto(out *VersionsQueryOptions) { + *out = *in + out.TypeMeta = in.TypeMeta + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VersionsQueryOptions. +func (in *VersionsQueryOptions) DeepCopy() *VersionsQueryOptions { + if in == nil { + return nil + } + out := new(VersionsQueryOptions) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VersionsQueryOptions) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} diff --git a/pkg/apis/dashboard/v1alpha1/zz_generated.defaults.go b/pkg/apis/dashboard/v1alpha1/zz_generated.defaults.go new file mode 100644 index 00000000000..0f877b0ee12 --- /dev/null +++ b/pkg/apis/dashboard/v1alpha1/zz_generated.defaults.go @@ -0,0 +1,19 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// SPDX-License-Identifier: AGPL-3.0-only + +// Code generated by defaulter-gen. DO NOT EDIT. + +package v1alpha1 + +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 +} diff --git a/pkg/apis/dashboard/v1alpha1/zz_generated.openapi.go b/pkg/apis/dashboard/v1alpha1/zz_generated.openapi.go new file mode 100644 index 00000000000..49d8328eee5 --- /dev/null +++ b/pkg/apis/dashboard/v1alpha1/zz_generated.openapi.go @@ -0,0 +1,685 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// SPDX-License-Identifier: AGPL-3.0-only + +// Code generated by openapi-gen. DO NOT EDIT. + +package v1alpha1 + +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/dashboard/v1alpha1.AnnotationActions": schema_pkg_apis_dashboard_v1alpha1_AnnotationActions(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.AnnotationPermission": schema_pkg_apis_dashboard_v1alpha1_AnnotationPermission(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.Dashboard": schema_pkg_apis_dashboard_v1alpha1_Dashboard(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardAccess": schema_pkg_apis_dashboard_v1alpha1_DashboardAccess(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardList": schema_pkg_apis_dashboard_v1alpha1_DashboardList(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardSpec": schema_pkg_apis_dashboard_v1alpha1_DashboardSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardVersionInfo": schema_pkg_apis_dashboard_v1alpha1_DashboardVersionInfo(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardVersionList": schema_pkg_apis_dashboard_v1alpha1_DashboardVersionList(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardWithAccessInfo": schema_pkg_apis_dashboard_v1alpha1_DashboardWithAccessInfo(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.LibraryPanel": schema_pkg_apis_dashboard_v1alpha1_LibraryPanel(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.LibraryPanelList": schema_pkg_apis_dashboard_v1alpha1_LibraryPanelList(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.LibraryPanelSpec": schema_pkg_apis_dashboard_v1alpha1_LibraryPanelSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.LibraryPanelStatus": schema_pkg_apis_dashboard_v1alpha1_LibraryPanelStatus(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.VersionsQueryOptions": schema_pkg_apis_dashboard_v1alpha1_VersionsQueryOptions(ref), + } +} + +func schema_pkg_apis_dashboard_v1alpha1_AnnotationActions(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "canAdd": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "canEdit": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "canDelete": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + }, + Required: []string{"canAdd", "canEdit", "canDelete"}, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v1alpha1_AnnotationPermission(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: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.AnnotationActions"), + }, + }, + "organization": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.AnnotationActions"), + }, + }, + }, + Required: []string{"dashboard", "organization"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.AnnotationActions"}, + } +} + +func schema_pkg_apis_dashboard_v1alpha1_Dashboard(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{ + Description: "Standard object's metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Description: "The dashboard body (unstructured for now)", + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardSpec"), + }, + }, + }, + Required: []string{"spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_pkg_apis_dashboard_v1alpha1_DashboardAccess(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Information about how the requesting user can use a given dashboard", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "slug": { + SchemaProps: spec.SchemaProps{ + Description: "Metadata fields", + Type: []string{"string"}, + Format: "", + }, + }, + "url": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "canSave": { + SchemaProps: spec.SchemaProps{ + Description: "The permissions part", + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "canEdit": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "canAdmin": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "canStar": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "canDelete": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "annotationsPermissions": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.AnnotationPermission"), + }, + }, + }, + Required: []string{"canSave", "canEdit", "canAdmin", "canStar", "canDelete", "annotationsPermissions"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.AnnotationPermission"}, + } +} + +func schema_pkg_apis_dashboard_v1alpha1_DashboardList(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/dashboard/v1alpha1.Dashboard"), + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.Dashboard", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + } +} + +func schema_pkg_apis_dashboard_v1alpha1_DashboardSpec(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: "", + }, + }, + "Object": { + SchemaProps: spec.SchemaProps{ + Description: "Object is a JSON compatible map with string, float, int, bool, []interface{}, or map[string]interface{} children.", + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Format: "", + }, + }, + }, + }, + }, + }, + Required: []string{"title", "Object"}, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v1alpha1_DashboardVersionInfo(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "version": { + SchemaProps: spec.SchemaProps{ + Description: "The internal ID for this version (will be replaced with resourceVersion)", + Default: 0, + Type: []string{"integer"}, + Format: "int32", + }, + }, + "parentVersion": { + SchemaProps: spec.SchemaProps{ + Description: "If the dashboard came from a previous version, it is set here", + Type: []string{"integer"}, + Format: "int32", + }, + }, + "created": { + SchemaProps: spec.SchemaProps{ + Description: "The creation timestamp for this version", + Default: 0, + Type: []string{"integer"}, + Format: "int64", + }, + }, + "createdBy": { + SchemaProps: spec.SchemaProps{ + Description: "The user who created this version", + Type: []string{"string"}, + Format: "", + }, + }, + "message": { + SchemaProps: spec.SchemaProps{ + Description: "Message passed while saving the version", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"version", "created"}, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v1alpha1_DashboardVersionList(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/dashboard/v1alpha1.DashboardVersionInfo"), + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardVersionInfo", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + } +} + +func schema_pkg_apis_dashboard_v1alpha1_DashboardWithAccessInfo(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "This is like the legacy DTO where access and metadata are all returned in a single call", + 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{ + Description: "Standard object's metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Description: "The dashboard body (unstructured for now)", + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardSpec"), + }, + }, + "access": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardAccess"), + }, + }, + }, + Required: []string{"spec", "access"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardAccess", "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_pkg_apis_dashboard_v1alpha1_LibraryPanel(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{ + Description: "Standard object's metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Description: "Panel properties", + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.LibraryPanelSpec"), + }, + }, + "status": { + SchemaProps: spec.SchemaProps{ + Description: "Status will show errors", + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.LibraryPanelStatus"), + }, + }, + }, + Required: []string{"spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.LibraryPanelSpec", "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.LibraryPanelStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_pkg_apis_dashboard_v1alpha1_LibraryPanelList(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/dashboard/v1alpha1.LibraryPanel"), + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.LibraryPanel", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + } +} + +func schema_pkg_apis_dashboard_v1alpha1_LibraryPanelSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "type": { + SchemaProps: spec.SchemaProps{ + Description: "The panel type", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "pluginVersion": { + SchemaProps: spec.SchemaProps{ + Description: "The panel type", + Type: []string{"string"}, + Format: "", + }, + }, + "title": { + SchemaProps: spec.SchemaProps{ + Description: "The panel title", + Type: []string{"string"}, + Format: "", + }, + }, + "description": { + SchemaProps: spec.SchemaProps{ + Description: "Library panel description", + Type: []string{"string"}, + Format: "", + }, + }, + "options": { + SchemaProps: spec.SchemaProps{ + Description: "The options schema depends on the panel type", + Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured"), + }, + }, + "fieldConfig": { + SchemaProps: spec.SchemaProps{ + Description: "The fieldConfig schema depends on the panel type", + Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured"), + }, + }, + "datasource": { + SchemaProps: spec.SchemaProps{ + Description: "The default datasource type", + Ref: ref("github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1.DataSourceRef"), + }, + }, + "targets": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "set", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "The datasource queries", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1.DataQuery"), + }, + }, + }, + }, + }, + }, + Required: []string{"type", "options", "fieldConfig"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1.DataQuery", "github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1.DataSourceRef", "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured"}, + } +} + +func schema_pkg_apis_dashboard_v1alpha1_LibraryPanelStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "warnings": { + SchemaProps: spec.SchemaProps{ + Description: "Translation warnings (mostly things that were in SQL columns but not found in the saved body)", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + "missing": { + SchemaProps: spec.SchemaProps{ + Description: "The properties previously stored in SQL that are not included in this model", + Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured"}, + } +} + +func schema_pkg_apis_dashboard_v1alpha1_VersionsQueryOptions(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: "", + }, + }, + "path": { + SchemaProps: spec.SchemaProps{ + Description: "Path is the URL path", + Type: []string{"string"}, + Format: "", + }, + }, + "version": { + SchemaProps: spec.SchemaProps{ + Type: []string{"integer"}, + Format: "int64", + }, + }, + }, + }, + }, + } +} diff --git a/pkg/apis/dashboard/v1alpha1/zz_generated.openapi_violation_exceptions.list b/pkg/apis/dashboard/v1alpha1/zz_generated.openapi_violation_exceptions.list new file mode 100644 index 00000000000..ee20d66be9c --- /dev/null +++ b/pkg/apis/dashboard/v1alpha1/zz_generated.openapi_violation_exceptions.list @@ -0,0 +1 @@ +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1,LibraryPanelStatus,Warnings diff --git a/pkg/apis/dashboard/v2alpha1/conversion.go b/pkg/apis/dashboard/v2alpha1/conversion.go new file mode 100644 index 00000000000..22db120c0e5 --- /dev/null +++ b/pkg/apis/dashboard/v2alpha1/conversion.go @@ -0,0 +1,32 @@ +package v2alpha1 + +import ( + conversion "k8s.io/apimachinery/pkg/conversion" + klog "k8s.io/klog/v2" + + common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" +) + +func Convert_v0alpha1_Unstructured_To_v2alpha1_DashboardSpec(in *common.Unstructured, out *DashboardSpec, s conversion.Scope) error { + out.Unstructured = *in + + t, ok := in.Object["title"] + if !ok { + return nil // skip setting the title if it's not in the unstructured object + } + + title, ok := t.(string) + if !ok { + klog.V(5).Infof("unstructured dashboard title field is not a string %v", t) + return nil // skip setting the title if it's not a string in the unstructured object + } + out.Title = title + + return nil +} + +func Convert_v2alpha1_DashboardSpec_To_v0alpha1_Unstructured(in *DashboardSpec, out *common.Unstructured, s conversion.Scope) error { + *out = in.Unstructured + out.Object["title"] = in.Title + return nil +} diff --git a/pkg/apis/dashboard/v2alpha1/conversion_test.go b/pkg/apis/dashboard/v2alpha1/conversion_test.go new file mode 100644 index 00000000000..143fdcffcef --- /dev/null +++ b/pkg/apis/dashboard/v2alpha1/conversion_test.go @@ -0,0 +1,65 @@ +package v2alpha1 + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" + + common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" +) + +func TestConvertDashboardVersions(t *testing.T) { + dashboardV0Spec := []byte(`{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations \u0026 Alerts", + "type": "dashboard" + } + ] + }, + "description": "", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 11711, + "links": [], + "panels": [], + "preload": false, + "schemaVersion": 40, + "tags": [], + "templating": { + "list": [] + }, + "timepicker": {}, + "timezone": "utc", + "title": "New dashboard", + "uid": "be3ymutzclgqod", + "version": 1, + "weekStart": "" +}`) + object := common.Unstructured{} + err := json.Unmarshal(dashboardV0Spec, &object.Object) + require.NoError(t, err) + result := DashboardSpec{} + // convert v0 to v2, where we should extract the title & all other elements should be copied + err = Convert_v0alpha1_Unstructured_To_v2alpha1_DashboardSpec(&object, &result, nil) + require.NoError(t, err) + require.Equal(t, result.Title, "New dashboard") + require.Equal(t, result.Unstructured, object) + + // now convert back & ensure it is the same + object2 := common.Unstructured{} + err = Convert_v2alpha1_DashboardSpec_To_v0alpha1_Unstructured(&result, &object2, nil) + require.NoError(t, err) + require.Equal(t, object, object2) +} diff --git a/pkg/apis/dashboard/v2alpha1/doc.go b/pkg/apis/dashboard/v2alpha1/doc.go new file mode 100644 index 00000000000..eac83f16cf9 --- /dev/null +++ b/pkg/apis/dashboard/v2alpha1/doc.go @@ -0,0 +1,7 @@ +// +k8s:deepcopy-gen=package +// +k8s:openapi-gen=true +// +k8s:defaulter-gen=TypeMeta +// +k8s:conversion-gen=github.com/grafana/grafana/pkg/apis/dashboard +// +groupName=dashboard.grafana.app + +package v2alpha1 // import "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1" diff --git a/pkg/apis/dashboard/v2alpha1/register.go b/pkg/apis/dashboard/v2alpha1/register.go new file mode 100644 index 00000000000..8ee9e149d7a --- /dev/null +++ b/pkg/apis/dashboard/v2alpha1/register.go @@ -0,0 +1,103 @@ +package v2alpha1 + +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 = "dashboard.grafana.app" + VERSION = "v2alpha1" + APIVERSION = GROUP + "/" + VERSION +) + +var DashboardResourceInfo = utils.NewResourceInfo(GROUP, VERSION, + "dashboards", "dashboard", "Dashboard", + func() runtime.Object { return &Dashboard{} }, + func() runtime.Object { return &DashboardList{} }, + utils.TableColumns{ + Definition: []metav1.TableColumnDefinition{ + {Name: "Name", Type: "string", Format: "name"}, + {Name: "Title", Type: "string", Format: "string", Description: "The dashboard name"}, + {Name: "Created At", Type: "date"}, + }, + Reader: func(obj any) ([]interface{}, error) { + dash, ok := obj.(*Dashboard) + if ok { + if dash != nil { + return []interface{}{ + dash.Name, + dash.Spec.GetNestedString("title"), + dash.CreationTimestamp.UTC().Format(time.RFC3339), + }, nil + } + } + return nil, fmt.Errorf("expected dashboard") + }, + }, +) + +var LibraryPanelResourceInfo = utils.NewResourceInfo(GROUP, VERSION, + "librarypanels", "librarypanel", "LibraryPanel", + func() runtime.Object { return &LibraryPanel{} }, + func() runtime.Object { return &LibraryPanelList{} }, + utils.TableColumns{ + Definition: []metav1.TableColumnDefinition{ + {Name: "Name", Type: "string", Format: "name"}, + {Name: "Title", Type: "string", Description: "The dashboard name"}, + {Name: "Type", Type: "string", Description: "the panel type"}, + {Name: "Created At", Type: "date"}, + }, + Reader: func(obj any) ([]interface{}, error) { + dash, ok := obj.(*LibraryPanel) + if ok { + if dash != nil { + return []interface{}{ + dash.Name, + dash.Spec.Title, + dash.Spec.Type, + dash.CreationTimestamp.UTC().Format(time.RFC3339), + }, nil + } + } + return nil, fmt.Errorf("expected library panel") + }, + }, +) + +var ( + SchemeBuilder runtime.SchemeBuilder + localSchemeBuilder = &SchemeBuilder + AddToScheme = localSchemeBuilder.AddToScheme + schemeGroupVersion = schema.GroupVersion{Group: GROUP, Version: VERSION} +) + +func init() { + localSchemeBuilder.Register(addKnownTypes, addDefaultingFuncs) +} + +// Adds the list of known types to the given scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(schemeGroupVersion, + &Dashboard{}, + &DashboardList{}, + &DashboardWithAccessInfo{}, + &DashboardVersionList{}, + &VersionsQueryOptions{}, + &LibraryPanel{}, + &LibraryPanelList{}, + &metav1.PartialObjectMetadata{}, + &metav1.PartialObjectMetadataList{}, + ) + metav1.AddToGroupVersion(scheme, schemeGroupVersion) + return nil +} + +func addDefaultingFuncs(scheme *runtime.Scheme) error { + return RegisterDefaults(scheme) +} diff --git a/pkg/apis/dashboard/v2alpha1/types.go b/pkg/apis/dashboard/v2alpha1/types.go new file mode 100644 index 00000000000..77cfbc9bce0 --- /dev/null +++ b/pkg/apis/dashboard/v2alpha1/types.go @@ -0,0 +1,166 @@ +package v2alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + data "github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1" + common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type Dashboard struct { + metav1.TypeMeta `json:",inline"` + // Standard object's metadata + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // The dashboard body (unstructured for now) + Spec DashboardSpec `json:"spec"` +} + +type DashboardSpec struct { + Title string `json:"title"` + common.Unstructured `json:",inline"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type DashboardList struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ListMeta `json:"metadata,omitempty"` + + Items []Dashboard `json:"items,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type DashboardVersionList struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ListMeta `json:"metadata,omitempty"` + + Items []DashboardVersionInfo `json:"items,omitempty"` +} + +type DashboardVersionInfo struct { + // The internal ID for this version (will be replaced with resourceVersion) + Version int `json:"version"` + + // If the dashboard came from a previous version, it is set here + ParentVersion int `json:"parentVersion,omitempty"` + + // The creation timestamp for this version + Created int64 `json:"created"` + + // The user who created this version + CreatedBy string `json:"createdBy,omitempty"` + + // Message passed while saving the version + Message string `json:"message,omitempty"` +} + +// +k8s:conversion-gen:explicit-from=net/url.Values +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type VersionsQueryOptions struct { + metav1.TypeMeta `json:",inline"` + + // Path is the URL path + // +optional + Path string `json:"path,omitempty"` + + // +optional + Version int64 `json:"version,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type LibraryPanel struct { + metav1.TypeMeta `json:",inline"` + // Standard object's metadata + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Panel properties + Spec LibraryPanelSpec `json:"spec"` + + // Status will show errors + Status *LibraryPanelStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type LibraryPanelList struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ListMeta `json:"metadata,omitempty"` + + Items []LibraryPanel `json:"items,omitempty"` +} + +type LibraryPanelSpec struct { + // The panel type + Type string `json:"type"` + + // The panel type + PluginVersion string `json:"pluginVersion,omitempty"` + + // The panel title + Title string `json:"title,omitempty"` + + // Library panel description + Description string `json:"description,omitempty"` + + // The options schema depends on the panel type + Options common.Unstructured `json:"options"` + + // The fieldConfig schema depends on the panel type + FieldConfig common.Unstructured `json:"fieldConfig"` + + // The default datasource type + Datasource *data.DataSourceRef `json:"datasource,omitempty"` + + // The datasource queries + // +listType=set + Targets []data.DataQuery `json:"targets,omitempty"` +} + +type LibraryPanelStatus struct { + // Translation warnings (mostly things that were in SQL columns but not found in the saved body) + Warnings []string `json:"warnings,omitempty"` + + // The properties previously stored in SQL that are not included in this model + Missing common.Unstructured `json:"missing,omitempty"` +} + +// This is like the legacy DTO where access and metadata are all returned in a single call +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type DashboardWithAccessInfo struct { + Dashboard `json:",inline"` + + Access DashboardAccess `json:"access"` +} + +// Information about how the requesting user can use a given dashboard +type DashboardAccess struct { + // Metadata fields + Slug string `json:"slug,omitempty"` + Url string `json:"url,omitempty"` + + // The permissions part + CanSave bool `json:"canSave"` + CanEdit bool `json:"canEdit"` + CanAdmin bool `json:"canAdmin"` + CanStar bool `json:"canStar"` + CanDelete bool `json:"canDelete"` + AnnotationsPermissions *AnnotationPermission `json:"annotationsPermissions"` +} + +type AnnotationPermission struct { + Dashboard AnnotationActions `json:"dashboard"` + Organization AnnotationActions `json:"organization"` +} + +type AnnotationActions struct { + CanAdd bool `json:"canAdd"` + CanEdit bool `json:"canEdit"` + CanDelete bool `json:"canDelete"` +} diff --git a/pkg/apis/dashboard/v2alpha1/zz_generated.conversion.go b/pkg/apis/dashboard/v2alpha1/zz_generated.conversion.go new file mode 100644 index 00000000000..ca42716b4e2 --- /dev/null +++ b/pkg/apis/dashboard/v2alpha1/zz_generated.conversion.go @@ -0,0 +1,563 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// SPDX-License-Identifier: AGPL-3.0-only + +// Code generated by conversion-gen. DO NOT EDIT. + +package v2alpha1 + +import ( + url "net/url" + unsafe "unsafe" + + datav0alpha1 "github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1" + v0alpha1 "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" + dashboard "github.com/grafana/grafana/pkg/apis/dashboard" + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*AnnotationActions)(nil), (*dashboard.AnnotationActions)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v2alpha1_AnnotationActions_To_dashboard_AnnotationActions(a.(*AnnotationActions), b.(*dashboard.AnnotationActions), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.AnnotationActions)(nil), (*AnnotationActions)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_AnnotationActions_To_v2alpha1_AnnotationActions(a.(*dashboard.AnnotationActions), b.(*AnnotationActions), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*AnnotationPermission)(nil), (*dashboard.AnnotationPermission)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v2alpha1_AnnotationPermission_To_dashboard_AnnotationPermission(a.(*AnnotationPermission), b.(*dashboard.AnnotationPermission), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.AnnotationPermission)(nil), (*AnnotationPermission)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_AnnotationPermission_To_v2alpha1_AnnotationPermission(a.(*dashboard.AnnotationPermission), b.(*AnnotationPermission), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*Dashboard)(nil), (*dashboard.Dashboard)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v2alpha1_Dashboard_To_dashboard_Dashboard(a.(*Dashboard), b.(*dashboard.Dashboard), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.Dashboard)(nil), (*Dashboard)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_Dashboard_To_v2alpha1_Dashboard(a.(*dashboard.Dashboard), b.(*Dashboard), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DashboardAccess)(nil), (*dashboard.DashboardAccess)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v2alpha1_DashboardAccess_To_dashboard_DashboardAccess(a.(*DashboardAccess), b.(*dashboard.DashboardAccess), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.DashboardAccess)(nil), (*DashboardAccess)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_DashboardAccess_To_v2alpha1_DashboardAccess(a.(*dashboard.DashboardAccess), b.(*DashboardAccess), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DashboardList)(nil), (*dashboard.DashboardList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v2alpha1_DashboardList_To_dashboard_DashboardList(a.(*DashboardList), b.(*dashboard.DashboardList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.DashboardList)(nil), (*DashboardList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_DashboardList_To_v2alpha1_DashboardList(a.(*dashboard.DashboardList), b.(*DashboardList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DashboardVersionInfo)(nil), (*dashboard.DashboardVersionInfo)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v2alpha1_DashboardVersionInfo_To_dashboard_DashboardVersionInfo(a.(*DashboardVersionInfo), b.(*dashboard.DashboardVersionInfo), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.DashboardVersionInfo)(nil), (*DashboardVersionInfo)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_DashboardVersionInfo_To_v2alpha1_DashboardVersionInfo(a.(*dashboard.DashboardVersionInfo), b.(*DashboardVersionInfo), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DashboardVersionList)(nil), (*dashboard.DashboardVersionList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v2alpha1_DashboardVersionList_To_dashboard_DashboardVersionList(a.(*DashboardVersionList), b.(*dashboard.DashboardVersionList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.DashboardVersionList)(nil), (*DashboardVersionList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_DashboardVersionList_To_v2alpha1_DashboardVersionList(a.(*dashboard.DashboardVersionList), b.(*DashboardVersionList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DashboardWithAccessInfo)(nil), (*dashboard.DashboardWithAccessInfo)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v2alpha1_DashboardWithAccessInfo_To_dashboard_DashboardWithAccessInfo(a.(*DashboardWithAccessInfo), b.(*dashboard.DashboardWithAccessInfo), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.DashboardWithAccessInfo)(nil), (*DashboardWithAccessInfo)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_DashboardWithAccessInfo_To_v2alpha1_DashboardWithAccessInfo(a.(*dashboard.DashboardWithAccessInfo), b.(*DashboardWithAccessInfo), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*LibraryPanel)(nil), (*dashboard.LibraryPanel)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v2alpha1_LibraryPanel_To_dashboard_LibraryPanel(a.(*LibraryPanel), b.(*dashboard.LibraryPanel), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.LibraryPanel)(nil), (*LibraryPanel)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_LibraryPanel_To_v2alpha1_LibraryPanel(a.(*dashboard.LibraryPanel), b.(*LibraryPanel), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*LibraryPanelList)(nil), (*dashboard.LibraryPanelList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v2alpha1_LibraryPanelList_To_dashboard_LibraryPanelList(a.(*LibraryPanelList), b.(*dashboard.LibraryPanelList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.LibraryPanelList)(nil), (*LibraryPanelList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_LibraryPanelList_To_v2alpha1_LibraryPanelList(a.(*dashboard.LibraryPanelList), b.(*LibraryPanelList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*LibraryPanelSpec)(nil), (*dashboard.LibraryPanelSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v2alpha1_LibraryPanelSpec_To_dashboard_LibraryPanelSpec(a.(*LibraryPanelSpec), b.(*dashboard.LibraryPanelSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.LibraryPanelSpec)(nil), (*LibraryPanelSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_LibraryPanelSpec_To_v2alpha1_LibraryPanelSpec(a.(*dashboard.LibraryPanelSpec), b.(*LibraryPanelSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*LibraryPanelStatus)(nil), (*dashboard.LibraryPanelStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v2alpha1_LibraryPanelStatus_To_dashboard_LibraryPanelStatus(a.(*LibraryPanelStatus), b.(*dashboard.LibraryPanelStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.LibraryPanelStatus)(nil), (*LibraryPanelStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_LibraryPanelStatus_To_v2alpha1_LibraryPanelStatus(a.(*dashboard.LibraryPanelStatus), b.(*LibraryPanelStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*VersionsQueryOptions)(nil), (*dashboard.VersionsQueryOptions)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v2alpha1_VersionsQueryOptions_To_dashboard_VersionsQueryOptions(a.(*VersionsQueryOptions), b.(*dashboard.VersionsQueryOptions), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*dashboard.VersionsQueryOptions)(nil), (*VersionsQueryOptions)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_dashboard_VersionsQueryOptions_To_v2alpha1_VersionsQueryOptions(a.(*dashboard.VersionsQueryOptions), b.(*VersionsQueryOptions), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*url.Values)(nil), (*VersionsQueryOptions)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_url_Values_To_v2alpha1_VersionsQueryOptions(a.(*url.Values), b.(*VersionsQueryOptions), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v0alpha1.Unstructured)(nil), (*DashboardSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v0alpha1_Unstructured_To_v2alpha1_DashboardSpec(a.(*v0alpha1.Unstructured), b.(*DashboardSpec), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*DashboardSpec)(nil), (*v0alpha1.Unstructured)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v2alpha1_DashboardSpec_To_v0alpha1_Unstructured(a.(*DashboardSpec), b.(*v0alpha1.Unstructured), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v2alpha1_AnnotationActions_To_dashboard_AnnotationActions(in *AnnotationActions, out *dashboard.AnnotationActions, s conversion.Scope) error { + out.CanAdd = in.CanAdd + out.CanEdit = in.CanEdit + out.CanDelete = in.CanDelete + return nil +} + +// Convert_v2alpha1_AnnotationActions_To_dashboard_AnnotationActions is an autogenerated conversion function. +func Convert_v2alpha1_AnnotationActions_To_dashboard_AnnotationActions(in *AnnotationActions, out *dashboard.AnnotationActions, s conversion.Scope) error { + return autoConvert_v2alpha1_AnnotationActions_To_dashboard_AnnotationActions(in, out, s) +} + +func autoConvert_dashboard_AnnotationActions_To_v2alpha1_AnnotationActions(in *dashboard.AnnotationActions, out *AnnotationActions, s conversion.Scope) error { + out.CanAdd = in.CanAdd + out.CanEdit = in.CanEdit + out.CanDelete = in.CanDelete + return nil +} + +// Convert_dashboard_AnnotationActions_To_v2alpha1_AnnotationActions is an autogenerated conversion function. +func Convert_dashboard_AnnotationActions_To_v2alpha1_AnnotationActions(in *dashboard.AnnotationActions, out *AnnotationActions, s conversion.Scope) error { + return autoConvert_dashboard_AnnotationActions_To_v2alpha1_AnnotationActions(in, out, s) +} + +func autoConvert_v2alpha1_AnnotationPermission_To_dashboard_AnnotationPermission(in *AnnotationPermission, out *dashboard.AnnotationPermission, s conversion.Scope) error { + if err := Convert_v2alpha1_AnnotationActions_To_dashboard_AnnotationActions(&in.Dashboard, &out.Dashboard, s); err != nil { + return err + } + if err := Convert_v2alpha1_AnnotationActions_To_dashboard_AnnotationActions(&in.Organization, &out.Organization, s); err != nil { + return err + } + return nil +} + +// Convert_v2alpha1_AnnotationPermission_To_dashboard_AnnotationPermission is an autogenerated conversion function. +func Convert_v2alpha1_AnnotationPermission_To_dashboard_AnnotationPermission(in *AnnotationPermission, out *dashboard.AnnotationPermission, s conversion.Scope) error { + return autoConvert_v2alpha1_AnnotationPermission_To_dashboard_AnnotationPermission(in, out, s) +} + +func autoConvert_dashboard_AnnotationPermission_To_v2alpha1_AnnotationPermission(in *dashboard.AnnotationPermission, out *AnnotationPermission, s conversion.Scope) error { + if err := Convert_dashboard_AnnotationActions_To_v2alpha1_AnnotationActions(&in.Dashboard, &out.Dashboard, s); err != nil { + return err + } + if err := Convert_dashboard_AnnotationActions_To_v2alpha1_AnnotationActions(&in.Organization, &out.Organization, s); err != nil { + return err + } + return nil +} + +// Convert_dashboard_AnnotationPermission_To_v2alpha1_AnnotationPermission is an autogenerated conversion function. +func Convert_dashboard_AnnotationPermission_To_v2alpha1_AnnotationPermission(in *dashboard.AnnotationPermission, out *AnnotationPermission, s conversion.Scope) error { + return autoConvert_dashboard_AnnotationPermission_To_v2alpha1_AnnotationPermission(in, out, s) +} + +func autoConvert_v2alpha1_Dashboard_To_dashboard_Dashboard(in *Dashboard, out *dashboard.Dashboard, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v2alpha1_DashboardSpec_To_v0alpha1_Unstructured(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +// Convert_v2alpha1_Dashboard_To_dashboard_Dashboard is an autogenerated conversion function. +func Convert_v2alpha1_Dashboard_To_dashboard_Dashboard(in *Dashboard, out *dashboard.Dashboard, s conversion.Scope) error { + return autoConvert_v2alpha1_Dashboard_To_dashboard_Dashboard(in, out, s) +} + +func autoConvert_dashboard_Dashboard_To_v2alpha1_Dashboard(in *dashboard.Dashboard, out *Dashboard, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v0alpha1_Unstructured_To_v2alpha1_DashboardSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +// Convert_dashboard_Dashboard_To_v2alpha1_Dashboard is an autogenerated conversion function. +func Convert_dashboard_Dashboard_To_v2alpha1_Dashboard(in *dashboard.Dashboard, out *Dashboard, s conversion.Scope) error { + return autoConvert_dashboard_Dashboard_To_v2alpha1_Dashboard(in, out, s) +} + +func autoConvert_v2alpha1_DashboardAccess_To_dashboard_DashboardAccess(in *DashboardAccess, out *dashboard.DashboardAccess, s conversion.Scope) error { + out.Slug = in.Slug + out.Url = in.Url + out.CanSave = in.CanSave + out.CanEdit = in.CanEdit + out.CanAdmin = in.CanAdmin + out.CanStar = in.CanStar + out.CanDelete = in.CanDelete + out.AnnotationsPermissions = (*dashboard.AnnotationPermission)(unsafe.Pointer(in.AnnotationsPermissions)) + return nil +} + +// Convert_v2alpha1_DashboardAccess_To_dashboard_DashboardAccess is an autogenerated conversion function. +func Convert_v2alpha1_DashboardAccess_To_dashboard_DashboardAccess(in *DashboardAccess, out *dashboard.DashboardAccess, s conversion.Scope) error { + return autoConvert_v2alpha1_DashboardAccess_To_dashboard_DashboardAccess(in, out, s) +} + +func autoConvert_dashboard_DashboardAccess_To_v2alpha1_DashboardAccess(in *dashboard.DashboardAccess, out *DashboardAccess, s conversion.Scope) error { + out.Slug = in.Slug + out.Url = in.Url + out.CanSave = in.CanSave + out.CanEdit = in.CanEdit + out.CanAdmin = in.CanAdmin + out.CanStar = in.CanStar + out.CanDelete = in.CanDelete + out.AnnotationsPermissions = (*AnnotationPermission)(unsafe.Pointer(in.AnnotationsPermissions)) + return nil +} + +// Convert_dashboard_DashboardAccess_To_v2alpha1_DashboardAccess is an autogenerated conversion function. +func Convert_dashboard_DashboardAccess_To_v2alpha1_DashboardAccess(in *dashboard.DashboardAccess, out *DashboardAccess, s conversion.Scope) error { + return autoConvert_dashboard_DashboardAccess_To_v2alpha1_DashboardAccess(in, out, s) +} + +func autoConvert_v2alpha1_DashboardList_To_dashboard_DashboardList(in *DashboardList, out *dashboard.DashboardList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]dashboard.Dashboard, len(*in)) + for i := range *in { + if err := Convert_v2alpha1_Dashboard_To_dashboard_Dashboard(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v2alpha1_DashboardList_To_dashboard_DashboardList is an autogenerated conversion function. +func Convert_v2alpha1_DashboardList_To_dashboard_DashboardList(in *DashboardList, out *dashboard.DashboardList, s conversion.Scope) error { + return autoConvert_v2alpha1_DashboardList_To_dashboard_DashboardList(in, out, s) +} + +func autoConvert_dashboard_DashboardList_To_v2alpha1_DashboardList(in *dashboard.DashboardList, out *DashboardList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Dashboard, len(*in)) + for i := range *in { + if err := Convert_dashboard_Dashboard_To_v2alpha1_Dashboard(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_dashboard_DashboardList_To_v2alpha1_DashboardList is an autogenerated conversion function. +func Convert_dashboard_DashboardList_To_v2alpha1_DashboardList(in *dashboard.DashboardList, out *DashboardList, s conversion.Scope) error { + return autoConvert_dashboard_DashboardList_To_v2alpha1_DashboardList(in, out, s) +} + +func autoConvert_v2alpha1_DashboardVersionInfo_To_dashboard_DashboardVersionInfo(in *DashboardVersionInfo, out *dashboard.DashboardVersionInfo, s conversion.Scope) error { + out.Version = in.Version + out.ParentVersion = in.ParentVersion + out.Created = in.Created + out.CreatedBy = in.CreatedBy + out.Message = in.Message + return nil +} + +// Convert_v2alpha1_DashboardVersionInfo_To_dashboard_DashboardVersionInfo is an autogenerated conversion function. +func Convert_v2alpha1_DashboardVersionInfo_To_dashboard_DashboardVersionInfo(in *DashboardVersionInfo, out *dashboard.DashboardVersionInfo, s conversion.Scope) error { + return autoConvert_v2alpha1_DashboardVersionInfo_To_dashboard_DashboardVersionInfo(in, out, s) +} + +func autoConvert_dashboard_DashboardVersionInfo_To_v2alpha1_DashboardVersionInfo(in *dashboard.DashboardVersionInfo, out *DashboardVersionInfo, s conversion.Scope) error { + out.Version = in.Version + out.ParentVersion = in.ParentVersion + out.Created = in.Created + out.CreatedBy = in.CreatedBy + out.Message = in.Message + return nil +} + +// Convert_dashboard_DashboardVersionInfo_To_v2alpha1_DashboardVersionInfo is an autogenerated conversion function. +func Convert_dashboard_DashboardVersionInfo_To_v2alpha1_DashboardVersionInfo(in *dashboard.DashboardVersionInfo, out *DashboardVersionInfo, s conversion.Scope) error { + return autoConvert_dashboard_DashboardVersionInfo_To_v2alpha1_DashboardVersionInfo(in, out, s) +} + +func autoConvert_v2alpha1_DashboardVersionList_To_dashboard_DashboardVersionList(in *DashboardVersionList, out *dashboard.DashboardVersionList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]dashboard.DashboardVersionInfo)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_v2alpha1_DashboardVersionList_To_dashboard_DashboardVersionList is an autogenerated conversion function. +func Convert_v2alpha1_DashboardVersionList_To_dashboard_DashboardVersionList(in *DashboardVersionList, out *dashboard.DashboardVersionList, s conversion.Scope) error { + return autoConvert_v2alpha1_DashboardVersionList_To_dashboard_DashboardVersionList(in, out, s) +} + +func autoConvert_dashboard_DashboardVersionList_To_v2alpha1_DashboardVersionList(in *dashboard.DashboardVersionList, out *DashboardVersionList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]DashboardVersionInfo)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_dashboard_DashboardVersionList_To_v2alpha1_DashboardVersionList is an autogenerated conversion function. +func Convert_dashboard_DashboardVersionList_To_v2alpha1_DashboardVersionList(in *dashboard.DashboardVersionList, out *DashboardVersionList, s conversion.Scope) error { + return autoConvert_dashboard_DashboardVersionList_To_v2alpha1_DashboardVersionList(in, out, s) +} + +func autoConvert_v2alpha1_DashboardWithAccessInfo_To_dashboard_DashboardWithAccessInfo(in *DashboardWithAccessInfo, out *dashboard.DashboardWithAccessInfo, s conversion.Scope) error { + if err := Convert_v2alpha1_Dashboard_To_dashboard_Dashboard(&in.Dashboard, &out.Dashboard, s); err != nil { + return err + } + if err := Convert_v2alpha1_DashboardAccess_To_dashboard_DashboardAccess(&in.Access, &out.Access, s); err != nil { + return err + } + return nil +} + +// Convert_v2alpha1_DashboardWithAccessInfo_To_dashboard_DashboardWithAccessInfo is an autogenerated conversion function. +func Convert_v2alpha1_DashboardWithAccessInfo_To_dashboard_DashboardWithAccessInfo(in *DashboardWithAccessInfo, out *dashboard.DashboardWithAccessInfo, s conversion.Scope) error { + return autoConvert_v2alpha1_DashboardWithAccessInfo_To_dashboard_DashboardWithAccessInfo(in, out, s) +} + +func autoConvert_dashboard_DashboardWithAccessInfo_To_v2alpha1_DashboardWithAccessInfo(in *dashboard.DashboardWithAccessInfo, out *DashboardWithAccessInfo, s conversion.Scope) error { + if err := Convert_dashboard_Dashboard_To_v2alpha1_Dashboard(&in.Dashboard, &out.Dashboard, s); err != nil { + return err + } + if err := Convert_dashboard_DashboardAccess_To_v2alpha1_DashboardAccess(&in.Access, &out.Access, s); err != nil { + return err + } + return nil +} + +// Convert_dashboard_DashboardWithAccessInfo_To_v2alpha1_DashboardWithAccessInfo is an autogenerated conversion function. +func Convert_dashboard_DashboardWithAccessInfo_To_v2alpha1_DashboardWithAccessInfo(in *dashboard.DashboardWithAccessInfo, out *DashboardWithAccessInfo, s conversion.Scope) error { + return autoConvert_dashboard_DashboardWithAccessInfo_To_v2alpha1_DashboardWithAccessInfo(in, out, s) +} + +func autoConvert_v2alpha1_LibraryPanel_To_dashboard_LibraryPanel(in *LibraryPanel, out *dashboard.LibraryPanel, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v2alpha1_LibraryPanelSpec_To_dashboard_LibraryPanelSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + out.Status = (*dashboard.LibraryPanelStatus)(unsafe.Pointer(in.Status)) + return nil +} + +// Convert_v2alpha1_LibraryPanel_To_dashboard_LibraryPanel is an autogenerated conversion function. +func Convert_v2alpha1_LibraryPanel_To_dashboard_LibraryPanel(in *LibraryPanel, out *dashboard.LibraryPanel, s conversion.Scope) error { + return autoConvert_v2alpha1_LibraryPanel_To_dashboard_LibraryPanel(in, out, s) +} + +func autoConvert_dashboard_LibraryPanel_To_v2alpha1_LibraryPanel(in *dashboard.LibraryPanel, out *LibraryPanel, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_dashboard_LibraryPanelSpec_To_v2alpha1_LibraryPanelSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + out.Status = (*LibraryPanelStatus)(unsafe.Pointer(in.Status)) + return nil +} + +// Convert_dashboard_LibraryPanel_To_v2alpha1_LibraryPanel is an autogenerated conversion function. +func Convert_dashboard_LibraryPanel_To_v2alpha1_LibraryPanel(in *dashboard.LibraryPanel, out *LibraryPanel, s conversion.Scope) error { + return autoConvert_dashboard_LibraryPanel_To_v2alpha1_LibraryPanel(in, out, s) +} + +func autoConvert_v2alpha1_LibraryPanelList_To_dashboard_LibraryPanelList(in *LibraryPanelList, out *dashboard.LibraryPanelList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]dashboard.LibraryPanel)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_v2alpha1_LibraryPanelList_To_dashboard_LibraryPanelList is an autogenerated conversion function. +func Convert_v2alpha1_LibraryPanelList_To_dashboard_LibraryPanelList(in *LibraryPanelList, out *dashboard.LibraryPanelList, s conversion.Scope) error { + return autoConvert_v2alpha1_LibraryPanelList_To_dashboard_LibraryPanelList(in, out, s) +} + +func autoConvert_dashboard_LibraryPanelList_To_v2alpha1_LibraryPanelList(in *dashboard.LibraryPanelList, out *LibraryPanelList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]LibraryPanel)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_dashboard_LibraryPanelList_To_v2alpha1_LibraryPanelList is an autogenerated conversion function. +func Convert_dashboard_LibraryPanelList_To_v2alpha1_LibraryPanelList(in *dashboard.LibraryPanelList, out *LibraryPanelList, s conversion.Scope) error { + return autoConvert_dashboard_LibraryPanelList_To_v2alpha1_LibraryPanelList(in, out, s) +} + +func autoConvert_v2alpha1_LibraryPanelSpec_To_dashboard_LibraryPanelSpec(in *LibraryPanelSpec, out *dashboard.LibraryPanelSpec, s conversion.Scope) error { + out.Type = in.Type + out.PluginVersion = in.PluginVersion + out.Title = in.Title + out.Description = in.Description + out.Options = in.Options + out.FieldConfig = in.FieldConfig + out.Datasource = (*datav0alpha1.DataSourceRef)(unsafe.Pointer(in.Datasource)) + out.Targets = *(*[]datav0alpha1.DataQuery)(unsafe.Pointer(&in.Targets)) + return nil +} + +// Convert_v2alpha1_LibraryPanelSpec_To_dashboard_LibraryPanelSpec is an autogenerated conversion function. +func Convert_v2alpha1_LibraryPanelSpec_To_dashboard_LibraryPanelSpec(in *LibraryPanelSpec, out *dashboard.LibraryPanelSpec, s conversion.Scope) error { + return autoConvert_v2alpha1_LibraryPanelSpec_To_dashboard_LibraryPanelSpec(in, out, s) +} + +func autoConvert_dashboard_LibraryPanelSpec_To_v2alpha1_LibraryPanelSpec(in *dashboard.LibraryPanelSpec, out *LibraryPanelSpec, s conversion.Scope) error { + out.Type = in.Type + out.PluginVersion = in.PluginVersion + out.Title = in.Title + out.Description = in.Description + out.Options = in.Options + out.FieldConfig = in.FieldConfig + out.Datasource = (*datav0alpha1.DataSourceRef)(unsafe.Pointer(in.Datasource)) + out.Targets = *(*[]datav0alpha1.DataQuery)(unsafe.Pointer(&in.Targets)) + return nil +} + +// Convert_dashboard_LibraryPanelSpec_To_v2alpha1_LibraryPanelSpec is an autogenerated conversion function. +func Convert_dashboard_LibraryPanelSpec_To_v2alpha1_LibraryPanelSpec(in *dashboard.LibraryPanelSpec, out *LibraryPanelSpec, s conversion.Scope) error { + return autoConvert_dashboard_LibraryPanelSpec_To_v2alpha1_LibraryPanelSpec(in, out, s) +} + +func autoConvert_v2alpha1_LibraryPanelStatus_To_dashboard_LibraryPanelStatus(in *LibraryPanelStatus, out *dashboard.LibraryPanelStatus, s conversion.Scope) error { + out.Warnings = *(*[]string)(unsafe.Pointer(&in.Warnings)) + out.Missing = in.Missing + return nil +} + +// Convert_v2alpha1_LibraryPanelStatus_To_dashboard_LibraryPanelStatus is an autogenerated conversion function. +func Convert_v2alpha1_LibraryPanelStatus_To_dashboard_LibraryPanelStatus(in *LibraryPanelStatus, out *dashboard.LibraryPanelStatus, s conversion.Scope) error { + return autoConvert_v2alpha1_LibraryPanelStatus_To_dashboard_LibraryPanelStatus(in, out, s) +} + +func autoConvert_dashboard_LibraryPanelStatus_To_v2alpha1_LibraryPanelStatus(in *dashboard.LibraryPanelStatus, out *LibraryPanelStatus, s conversion.Scope) error { + out.Warnings = *(*[]string)(unsafe.Pointer(&in.Warnings)) + out.Missing = in.Missing + return nil +} + +// Convert_dashboard_LibraryPanelStatus_To_v2alpha1_LibraryPanelStatus is an autogenerated conversion function. +func Convert_dashboard_LibraryPanelStatus_To_v2alpha1_LibraryPanelStatus(in *dashboard.LibraryPanelStatus, out *LibraryPanelStatus, s conversion.Scope) error { + return autoConvert_dashboard_LibraryPanelStatus_To_v2alpha1_LibraryPanelStatus(in, out, s) +} + +func autoConvert_v2alpha1_VersionsQueryOptions_To_dashboard_VersionsQueryOptions(in *VersionsQueryOptions, out *dashboard.VersionsQueryOptions, s conversion.Scope) error { + out.Path = in.Path + out.Version = in.Version + return nil +} + +// Convert_v2alpha1_VersionsQueryOptions_To_dashboard_VersionsQueryOptions is an autogenerated conversion function. +func Convert_v2alpha1_VersionsQueryOptions_To_dashboard_VersionsQueryOptions(in *VersionsQueryOptions, out *dashboard.VersionsQueryOptions, s conversion.Scope) error { + return autoConvert_v2alpha1_VersionsQueryOptions_To_dashboard_VersionsQueryOptions(in, out, s) +} + +func autoConvert_dashboard_VersionsQueryOptions_To_v2alpha1_VersionsQueryOptions(in *dashboard.VersionsQueryOptions, out *VersionsQueryOptions, s conversion.Scope) error { + out.Path = in.Path + out.Version = in.Version + return nil +} + +// Convert_dashboard_VersionsQueryOptions_To_v2alpha1_VersionsQueryOptions is an autogenerated conversion function. +func Convert_dashboard_VersionsQueryOptions_To_v2alpha1_VersionsQueryOptions(in *dashboard.VersionsQueryOptions, out *VersionsQueryOptions, s conversion.Scope) error { + return autoConvert_dashboard_VersionsQueryOptions_To_v2alpha1_VersionsQueryOptions(in, out, s) +} + +func autoConvert_url_Values_To_v2alpha1_VersionsQueryOptions(in *url.Values, out *VersionsQueryOptions, s conversion.Scope) error { + // WARNING: Field TypeMeta does not have json tag, skipping. + + if values, ok := map[string][]string(*in)["path"]; ok && len(values) > 0 { + if err := runtime.Convert_Slice_string_To_string(&values, &out.Path, s); err != nil { + return err + } + } else { + out.Path = "" + } + if values, ok := map[string][]string(*in)["version"]; ok && len(values) > 0 { + if err := runtime.Convert_Slice_string_To_int64(&values, &out.Version, s); err != nil { + return err + } + } else { + out.Version = 0 + } + return nil +} + +// Convert_url_Values_To_v2alpha1_VersionsQueryOptions is an autogenerated conversion function. +func Convert_url_Values_To_v2alpha1_VersionsQueryOptions(in *url.Values, out *VersionsQueryOptions, s conversion.Scope) error { + return autoConvert_url_Values_To_v2alpha1_VersionsQueryOptions(in, out, s) +} diff --git a/pkg/apis/dashboard/v2alpha1/zz_generated.deepcopy.go b/pkg/apis/dashboard/v2alpha1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..96d621a5263 --- /dev/null +++ b/pkg/apis/dashboard/v2alpha1/zz_generated.deepcopy.go @@ -0,0 +1,360 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// SPDX-License-Identifier: AGPL-3.0-only + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v2alpha1 + +import ( + v0alpha1 "github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1" + 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 *AnnotationActions) DeepCopyInto(out *AnnotationActions) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnnotationActions. +func (in *AnnotationActions) DeepCopy() *AnnotationActions { + if in == nil { + return nil + } + out := new(AnnotationActions) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AnnotationPermission) DeepCopyInto(out *AnnotationPermission) { + *out = *in + out.Dashboard = in.Dashboard + out.Organization = in.Organization + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnnotationPermission. +func (in *AnnotationPermission) DeepCopy() *AnnotationPermission { + if in == nil { + return nil + } + out := new(AnnotationPermission) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Dashboard) DeepCopyInto(out *Dashboard) { + *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 Dashboard. +func (in *Dashboard) DeepCopy() *Dashboard { + if in == nil { + return nil + } + out := new(Dashboard) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Dashboard) 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 *DashboardAccess) DeepCopyInto(out *DashboardAccess) { + *out = *in + if in.AnnotationsPermissions != nil { + in, out := &in.AnnotationsPermissions, &out.AnnotationsPermissions + *out = new(AnnotationPermission) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardAccess. +func (in *DashboardAccess) DeepCopy() *DashboardAccess { + if in == nil { + return nil + } + out := new(DashboardAccess) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DashboardList) DeepCopyInto(out *DashboardList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Dashboard, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardList. +func (in *DashboardList) DeepCopy() *DashboardList { + if in == nil { + return nil + } + out := new(DashboardList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DashboardList) 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 *DashboardSpec) DeepCopyInto(out *DashboardSpec) { + *out = *in + in.Unstructured.DeepCopyInto(&out.Unstructured) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardSpec. +func (in *DashboardSpec) DeepCopy() *DashboardSpec { + if in == nil { + return nil + } + out := new(DashboardSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DashboardVersionInfo) DeepCopyInto(out *DashboardVersionInfo) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardVersionInfo. +func (in *DashboardVersionInfo) DeepCopy() *DashboardVersionInfo { + if in == nil { + return nil + } + out := new(DashboardVersionInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DashboardVersionList) DeepCopyInto(out *DashboardVersionList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]DashboardVersionInfo, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardVersionList. +func (in *DashboardVersionList) DeepCopy() *DashboardVersionList { + if in == nil { + return nil + } + out := new(DashboardVersionList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DashboardVersionList) 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 *DashboardWithAccessInfo) DeepCopyInto(out *DashboardWithAccessInfo) { + *out = *in + in.Dashboard.DeepCopyInto(&out.Dashboard) + in.Access.DeepCopyInto(&out.Access) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardWithAccessInfo. +func (in *DashboardWithAccessInfo) DeepCopy() *DashboardWithAccessInfo { + if in == nil { + return nil + } + out := new(DashboardWithAccessInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DashboardWithAccessInfo) 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 *LibraryPanel) DeepCopyInto(out *LibraryPanel) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + if in.Status != nil { + in, out := &in.Status, &out.Status + *out = new(LibraryPanelStatus) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LibraryPanel. +func (in *LibraryPanel) DeepCopy() *LibraryPanel { + if in == nil { + return nil + } + out := new(LibraryPanel) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *LibraryPanel) 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 *LibraryPanelList) DeepCopyInto(out *LibraryPanelList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]LibraryPanel, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LibraryPanelList. +func (in *LibraryPanelList) DeepCopy() *LibraryPanelList { + if in == nil { + return nil + } + out := new(LibraryPanelList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *LibraryPanelList) 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 *LibraryPanelSpec) DeepCopyInto(out *LibraryPanelSpec) { + *out = *in + in.Options.DeepCopyInto(&out.Options) + in.FieldConfig.DeepCopyInto(&out.FieldConfig) + if in.Datasource != nil { + in, out := &in.Datasource, &out.Datasource + *out = new(v0alpha1.DataSourceRef) + **out = **in + } + if in.Targets != nil { + in, out := &in.Targets, &out.Targets + *out = make([]v0alpha1.DataQuery, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LibraryPanelSpec. +func (in *LibraryPanelSpec) DeepCopy() *LibraryPanelSpec { + if in == nil { + return nil + } + out := new(LibraryPanelSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LibraryPanelStatus) DeepCopyInto(out *LibraryPanelStatus) { + *out = *in + if in.Warnings != nil { + in, out := &in.Warnings, &out.Warnings + *out = make([]string, len(*in)) + copy(*out, *in) + } + in.Missing.DeepCopyInto(&out.Missing) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LibraryPanelStatus. +func (in *LibraryPanelStatus) DeepCopy() *LibraryPanelStatus { + if in == nil { + return nil + } + out := new(LibraryPanelStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VersionsQueryOptions) DeepCopyInto(out *VersionsQueryOptions) { + *out = *in + out.TypeMeta = in.TypeMeta + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VersionsQueryOptions. +func (in *VersionsQueryOptions) DeepCopy() *VersionsQueryOptions { + if in == nil { + return nil + } + out := new(VersionsQueryOptions) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VersionsQueryOptions) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} diff --git a/pkg/apis/dashboard/v2alpha1/zz_generated.defaults.go b/pkg/apis/dashboard/v2alpha1/zz_generated.defaults.go new file mode 100644 index 00000000000..98e576fa55c --- /dev/null +++ b/pkg/apis/dashboard/v2alpha1/zz_generated.defaults.go @@ -0,0 +1,19 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// SPDX-License-Identifier: AGPL-3.0-only + +// Code generated by defaulter-gen. DO NOT EDIT. + +package v2alpha1 + +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 +} diff --git a/pkg/apis/dashboard/v2alpha1/zz_generated.openapi.go b/pkg/apis/dashboard/v2alpha1/zz_generated.openapi.go new file mode 100644 index 00000000000..5658b9dc8d7 --- /dev/null +++ b/pkg/apis/dashboard/v2alpha1/zz_generated.openapi.go @@ -0,0 +1,685 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// SPDX-License-Identifier: AGPL-3.0-only + +// Code generated by openapi-gen. DO NOT EDIT. + +package v2alpha1 + +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/dashboard/v2alpha1.AnnotationActions": schema_pkg_apis_dashboard_v2alpha1_AnnotationActions(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.AnnotationPermission": schema_pkg_apis_dashboard_v2alpha1_AnnotationPermission(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.Dashboard": schema_pkg_apis_dashboard_v2alpha1_Dashboard(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardAccess": schema_pkg_apis_dashboard_v2alpha1_DashboardAccess(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardList": schema_pkg_apis_dashboard_v2alpha1_DashboardList(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVersionInfo": schema_pkg_apis_dashboard_v2alpha1_DashboardVersionInfo(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVersionList": schema_pkg_apis_dashboard_v2alpha1_DashboardVersionList(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardWithAccessInfo": schema_pkg_apis_dashboard_v2alpha1_DashboardWithAccessInfo(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.LibraryPanel": schema_pkg_apis_dashboard_v2alpha1_LibraryPanel(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.LibraryPanelList": schema_pkg_apis_dashboard_v2alpha1_LibraryPanelList(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.LibraryPanelSpec": schema_pkg_apis_dashboard_v2alpha1_LibraryPanelSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.LibraryPanelStatus": schema_pkg_apis_dashboard_v2alpha1_LibraryPanelStatus(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.VersionsQueryOptions": schema_pkg_apis_dashboard_v2alpha1_VersionsQueryOptions(ref), + } +} + +func schema_pkg_apis_dashboard_v2alpha1_AnnotationActions(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "canAdd": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "canEdit": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "canDelete": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + }, + Required: []string{"canAdd", "canEdit", "canDelete"}, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_AnnotationPermission(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: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.AnnotationActions"), + }, + }, + "organization": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.AnnotationActions"), + }, + }, + }, + Required: []string{"dashboard", "organization"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.AnnotationActions"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_Dashboard(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{ + Description: "Standard object's metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Description: "The dashboard body (unstructured for now)", + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardSpec"), + }, + }, + }, + Required: []string{"spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardAccess(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Information about how the requesting user can use a given dashboard", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "slug": { + SchemaProps: spec.SchemaProps{ + Description: "Metadata fields", + Type: []string{"string"}, + Format: "", + }, + }, + "url": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "canSave": { + SchemaProps: spec.SchemaProps{ + Description: "The permissions part", + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "canEdit": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "canAdmin": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "canStar": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "canDelete": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "annotationsPermissions": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.AnnotationPermission"), + }, + }, + }, + Required: []string{"canSave", "canEdit", "canAdmin", "canStar", "canDelete", "annotationsPermissions"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.AnnotationPermission"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardList(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/dashboard/v2alpha1.Dashboard"), + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.Dashboard", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardSpec(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: "", + }, + }, + "Object": { + SchemaProps: spec.SchemaProps{ + Description: "Object is a JSON compatible map with string, float, int, bool, []interface{}, or map[string]interface{} children.", + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Format: "", + }, + }, + }, + }, + }, + }, + Required: []string{"title", "Object"}, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardVersionInfo(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "version": { + SchemaProps: spec.SchemaProps{ + Description: "The internal ID for this version (will be replaced with resourceVersion)", + Default: 0, + Type: []string{"integer"}, + Format: "int32", + }, + }, + "parentVersion": { + SchemaProps: spec.SchemaProps{ + Description: "If the dashboard came from a previous version, it is set here", + Type: []string{"integer"}, + Format: "int32", + }, + }, + "created": { + SchemaProps: spec.SchemaProps{ + Description: "The creation timestamp for this version", + Default: 0, + Type: []string{"integer"}, + Format: "int64", + }, + }, + "createdBy": { + SchemaProps: spec.SchemaProps{ + Description: "The user who created this version", + Type: []string{"string"}, + Format: "", + }, + }, + "message": { + SchemaProps: spec.SchemaProps{ + Description: "Message passed while saving the version", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"version", "created"}, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardVersionList(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/dashboard/v2alpha1.DashboardVersionInfo"), + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVersionInfo", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardWithAccessInfo(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "This is like the legacy DTO where access and metadata are all returned in a single call", + 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{ + Description: "Standard object's metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Description: "The dashboard body (unstructured for now)", + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardSpec"), + }, + }, + "access": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardAccess"), + }, + }, + }, + Required: []string{"spec", "access"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardAccess", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_LibraryPanel(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{ + Description: "Standard object's metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Description: "Panel properties", + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.LibraryPanelSpec"), + }, + }, + "status": { + SchemaProps: spec.SchemaProps{ + Description: "Status will show errors", + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.LibraryPanelStatus"), + }, + }, + }, + Required: []string{"spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.LibraryPanelSpec", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.LibraryPanelStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_LibraryPanelList(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/dashboard/v2alpha1.LibraryPanel"), + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.LibraryPanel", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_LibraryPanelSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "type": { + SchemaProps: spec.SchemaProps{ + Description: "The panel type", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "pluginVersion": { + SchemaProps: spec.SchemaProps{ + Description: "The panel type", + Type: []string{"string"}, + Format: "", + }, + }, + "title": { + SchemaProps: spec.SchemaProps{ + Description: "The panel title", + Type: []string{"string"}, + Format: "", + }, + }, + "description": { + SchemaProps: spec.SchemaProps{ + Description: "Library panel description", + Type: []string{"string"}, + Format: "", + }, + }, + "options": { + SchemaProps: spec.SchemaProps{ + Description: "The options schema depends on the panel type", + Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured"), + }, + }, + "fieldConfig": { + SchemaProps: spec.SchemaProps{ + Description: "The fieldConfig schema depends on the panel type", + Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured"), + }, + }, + "datasource": { + SchemaProps: spec.SchemaProps{ + Description: "The default datasource type", + Ref: ref("github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1.DataSourceRef"), + }, + }, + "targets": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "set", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "The datasource queries", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1.DataQuery"), + }, + }, + }, + }, + }, + }, + Required: []string{"type", "options", "fieldConfig"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1.DataQuery", "github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1.DataSourceRef", "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_LibraryPanelStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "warnings": { + SchemaProps: spec.SchemaProps{ + Description: "Translation warnings (mostly things that were in SQL columns but not found in the saved body)", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + "missing": { + SchemaProps: spec.SchemaProps{ + Description: "The properties previously stored in SQL that are not included in this model", + Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_VersionsQueryOptions(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: "", + }, + }, + "path": { + SchemaProps: spec.SchemaProps{ + Description: "Path is the URL path", + Type: []string{"string"}, + Format: "", + }, + }, + "version": { + SchemaProps: spec.SchemaProps{ + Type: []string{"integer"}, + Format: "int64", + }, + }, + }, + }, + }, + } +} diff --git a/pkg/apis/dashboard/v2alpha1/zz_generated.openapi_violation_exceptions.list b/pkg/apis/dashboard/v2alpha1/zz_generated.openapi_violation_exceptions.list new file mode 100644 index 00000000000..2277dc1bbe4 --- /dev/null +++ b/pkg/apis/dashboard/v2alpha1/zz_generated.openapi_violation_exceptions.list @@ -0,0 +1 @@ +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,LibraryPanelStatus,Warnings diff --git a/pkg/apis/dashboard/zz_generated.deepcopy.go b/pkg/apis/dashboard/zz_generated.deepcopy.go new file mode 100644 index 00000000000..af600f721b6 --- /dev/null +++ b/pkg/apis/dashboard/zz_generated.deepcopy.go @@ -0,0 +1,343 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// SPDX-License-Identifier: AGPL-3.0-only + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package dashboard + +import ( + v0alpha1 "github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1" + 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 *AnnotationActions) DeepCopyInto(out *AnnotationActions) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnnotationActions. +func (in *AnnotationActions) DeepCopy() *AnnotationActions { + if in == nil { + return nil + } + out := new(AnnotationActions) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AnnotationPermission) DeepCopyInto(out *AnnotationPermission) { + *out = *in + out.Dashboard = in.Dashboard + out.Organization = in.Organization + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnnotationPermission. +func (in *AnnotationPermission) DeepCopy() *AnnotationPermission { + if in == nil { + return nil + } + out := new(AnnotationPermission) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Dashboard) DeepCopyInto(out *Dashboard) { + *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 Dashboard. +func (in *Dashboard) DeepCopy() *Dashboard { + if in == nil { + return nil + } + out := new(Dashboard) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Dashboard) 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 *DashboardAccess) DeepCopyInto(out *DashboardAccess) { + *out = *in + if in.AnnotationsPermissions != nil { + in, out := &in.AnnotationsPermissions, &out.AnnotationsPermissions + *out = new(AnnotationPermission) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardAccess. +func (in *DashboardAccess) DeepCopy() *DashboardAccess { + if in == nil { + return nil + } + out := new(DashboardAccess) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DashboardList) DeepCopyInto(out *DashboardList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Dashboard, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardList. +func (in *DashboardList) DeepCopy() *DashboardList { + if in == nil { + return nil + } + out := new(DashboardList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DashboardList) 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 *DashboardVersionInfo) DeepCopyInto(out *DashboardVersionInfo) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardVersionInfo. +func (in *DashboardVersionInfo) DeepCopy() *DashboardVersionInfo { + if in == nil { + return nil + } + out := new(DashboardVersionInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DashboardVersionList) DeepCopyInto(out *DashboardVersionList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]DashboardVersionInfo, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardVersionList. +func (in *DashboardVersionList) DeepCopy() *DashboardVersionList { + if in == nil { + return nil + } + out := new(DashboardVersionList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DashboardVersionList) 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 *DashboardWithAccessInfo) DeepCopyInto(out *DashboardWithAccessInfo) { + *out = *in + in.Dashboard.DeepCopyInto(&out.Dashboard) + in.Access.DeepCopyInto(&out.Access) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardWithAccessInfo. +func (in *DashboardWithAccessInfo) DeepCopy() *DashboardWithAccessInfo { + if in == nil { + return nil + } + out := new(DashboardWithAccessInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DashboardWithAccessInfo) 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 *LibraryPanel) DeepCopyInto(out *LibraryPanel) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + if in.Status != nil { + in, out := &in.Status, &out.Status + *out = new(LibraryPanelStatus) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LibraryPanel. +func (in *LibraryPanel) DeepCopy() *LibraryPanel { + if in == nil { + return nil + } + out := new(LibraryPanel) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *LibraryPanel) 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 *LibraryPanelList) DeepCopyInto(out *LibraryPanelList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]LibraryPanel, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LibraryPanelList. +func (in *LibraryPanelList) DeepCopy() *LibraryPanelList { + if in == nil { + return nil + } + out := new(LibraryPanelList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *LibraryPanelList) 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 *LibraryPanelSpec) DeepCopyInto(out *LibraryPanelSpec) { + *out = *in + in.Options.DeepCopyInto(&out.Options) + in.FieldConfig.DeepCopyInto(&out.FieldConfig) + if in.Datasource != nil { + in, out := &in.Datasource, &out.Datasource + *out = new(v0alpha1.DataSourceRef) + **out = **in + } + if in.Targets != nil { + in, out := &in.Targets, &out.Targets + *out = make([]v0alpha1.DataQuery, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LibraryPanelSpec. +func (in *LibraryPanelSpec) DeepCopy() *LibraryPanelSpec { + if in == nil { + return nil + } + out := new(LibraryPanelSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LibraryPanelStatus) DeepCopyInto(out *LibraryPanelStatus) { + *out = *in + if in.Warnings != nil { + in, out := &in.Warnings, &out.Warnings + *out = make([]string, len(*in)) + copy(*out, *in) + } + in.Missing.DeepCopyInto(&out.Missing) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LibraryPanelStatus. +func (in *LibraryPanelStatus) DeepCopy() *LibraryPanelStatus { + if in == nil { + return nil + } + out := new(LibraryPanelStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VersionsQueryOptions) DeepCopyInto(out *VersionsQueryOptions) { + *out = *in + out.TypeMeta = in.TypeMeta + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VersionsQueryOptions. +func (in *VersionsQueryOptions) DeepCopy() *VersionsQueryOptions { + if in == nil { + return nil + } + out := new(VersionsQueryOptions) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VersionsQueryOptions) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} diff --git a/pkg/registry/apis/apis.go b/pkg/registry/apis/apis.go index 849554dbbfb..c358fbac006 100644 --- a/pkg/registry/apis/apis.go +++ b/pkg/registry/apis/apis.go @@ -2,7 +2,10 @@ package apiregistry import ( "github.com/grafana/grafana/pkg/registry/apis/alerting/notifications" - "github.com/grafana/grafana/pkg/registry/apis/dashboard" + dashboardinternal "github.com/grafana/grafana/pkg/registry/apis/dashboard" + dashboardv0alpha1 "github.com/grafana/grafana/pkg/registry/apis/dashboard/v0alpha1" + dashboardv1alpha1 "github.com/grafana/grafana/pkg/registry/apis/dashboard/v1alpha1" + dashboardv2alpha1 "github.com/grafana/grafana/pkg/registry/apis/dashboard/v2alpha1" "github.com/grafana/grafana/pkg/registry/apis/dashboardsnapshot" "github.com/grafana/grafana/pkg/registry/apis/datasource" "github.com/grafana/grafana/pkg/registry/apis/featuretoggle" @@ -20,7 +23,10 @@ type Service struct{} // ProvideRegistryServiceSink is an entry point for each service that will force initialization // and give each builder the chance to register itself with the main server func ProvideRegistryServiceSink( - _ *dashboard.DashboardsAPIBuilder, + _ *dashboardinternal.DashboardsAPIBuilder, + _ *dashboardv0alpha1.DashboardsAPIBuilder, + _ *dashboardv1alpha1.DashboardsAPIBuilder, + _ *dashboardv2alpha1.DashboardsAPIBuilder, _ *dashboardsnapshot.SnapshotsAPIBuilder, _ *featuretoggle.FeatureFlagAPIBuilder, _ *datasource.DataSourceAPIBuilder, diff --git a/pkg/registry/apis/dashboard/authorizer.go b/pkg/registry/apis/dashboard/authorizer.go index b3fe891e4c6..d7c02a9c159 100644 --- a/pkg/registry/apis/dashboard/authorizer.go +++ b/pkg/registry/apis/dashboard/authorizer.go @@ -7,12 +7,13 @@ import ( "github.com/grafana/authlib/claims" "github.com/grafana/grafana/pkg/apimachinery/identity" - "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1" + "github.com/grafana/grafana/pkg/apis/dashboard" + "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/guardian" ) -func (b *DashboardsAPIBuilder) GetAuthorizer() authorizer.Authorizer { +func GetAuthorizer(dashboardService dashboards.DashboardService, l log.Logger) authorizer.Authorizer { return authorizer.AuthorizerFunc( func(ctx context.Context, attr authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) { if !attr.IsResourceRequest() { @@ -26,7 +27,7 @@ func (b *DashboardsAPIBuilder) GetAuthorizer() authorizer.Authorizer { if attr.GetName() == "" { // Discourage use of the "list" command for non super admin users - if attr.GetVerb() == "list" && attr.GetResource() == v0alpha1.DashboardResourceInfo.GroupResource().Resource { + if attr.GetVerb() == "list" && attr.GetResource() == dashboard.DashboardResourceInfo.GroupResource().Resource { if !user.GetIsGrafanaAdmin() { return authorizer.DecisionDeny, "list summary objects (or connect as GrafanaAdmin)", err } @@ -45,7 +46,7 @@ func (b *DashboardsAPIBuilder) GetAuthorizer() authorizer.Authorizer { } // expensive path to lookup permissions for a single dashboard - dto, err := b.dashboardService.GetDashboard(ctx, &dashboards.GetDashboardQuery{ + dto, err := dashboardService.GetDashboard(ctx, &dashboards.GetDashboardQuery{ UID: attr.GetName(), OrgID: info.OrgID, }) @@ -87,7 +88,7 @@ func (b *DashboardsAPIBuilder) GetAuthorizer() authorizer.Authorizer { return authorizer.DecisionDeny, "can not delete dashboard", err } default: - b.log.Info("unknown verb", "verb", attr.GetVerb()) + l.Info("unknown verb", "verb", attr.GetVerb()) return authorizer.DecisionNoOpinion, "unsupported verb", nil // Unknown verb } return authorizer.DecisionAllow, "", nil diff --git a/pkg/registry/apis/dashboard/conversion.go b/pkg/registry/apis/dashboard/conversion.go new file mode 100644 index 00000000000..c4272a06b26 --- /dev/null +++ b/pkg/registry/apis/dashboard/conversion.go @@ -0,0 +1,14 @@ +package dashboard + +import ( + "github.com/grafana/grafana/pkg/apis/dashboard" + "k8s.io/apimachinery/pkg/runtime" +) + +func ToInternalDashboard(scheme *runtime.Scheme, obj runtime.Object) (*dashboard.Dashboard, error) { + dash := &dashboard.Dashboard{} + if err := scheme.Convert(obj, dash, nil); err != nil { + return nil, err + } + return dash, nil +} diff --git a/pkg/registry/apis/dashboard/conversion_test.go b/pkg/registry/apis/dashboard/conversion_test.go new file mode 100644 index 00000000000..8953e647d9a --- /dev/null +++ b/pkg/registry/apis/dashboard/conversion_test.go @@ -0,0 +1,106 @@ +package dashboard + +import ( + "testing" + "time" + + common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" + dashboardinternal "github.com/grafana/grafana/pkg/apis/dashboard" + dashboardv0alpha1 "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1" + dashboardv1alpha1 "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1" + dashboardv2alpha1 "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1" + "github.com/stretchr/testify/require" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +func TestConvertDashboardVersionsToInternal(t *testing.T) { + // create the scheme of all the dashboard versions + // it's all a part of the grand scheme - ‿ - + scheme := runtime.NewScheme() + err := dashboardv0alpha1.AddToScheme(scheme) + require.NoError(t, err) + err = dashboardv1alpha1.AddToScheme(scheme) + require.NoError(t, err) + err = dashboardv2alpha1.AddToScheme(scheme) + require.NoError(t, err) + err = dashboardinternal.AddToScheme(scheme) + require.NoError(t, err) + + // all dashboard versions in this test have the same info inside + // so, the internal version should be the same when going back and forth + creationTimestamp := time.Now() + name := "test" + title := "New dashboard" + namespace := "default" + annotations := map[string]string{"created-by": "me"} + labels := map[string]string{"starred-by": "you"} + rv := "1" + body := map[string]interface{}{"title": title, "description": "A new dashboard"} + expectedDashbaord := dashboardinternal.Dashboard{ + ObjectMeta: v1.ObjectMeta{ + Name: name, + Namespace: namespace, + CreationTimestamp: v1.NewTime(creationTimestamp), + Annotations: annotations, + Labels: labels, + ResourceVersion: rv, + }, + Spec: common.Unstructured{ + Object: body, + }, + } + dashV0 := &dashboardv0alpha1.Dashboard{ + ObjectMeta: v1.ObjectMeta{ + Name: name, + Namespace: namespace, + CreationTimestamp: v1.NewTime(creationTimestamp), + Annotations: annotations, + Labels: labels, + ResourceVersion: rv, + }, + Spec: common.Unstructured{ + Object: body, + }, + } + + dash, err := ToInternalDashboard(scheme, dashV0) + require.NoError(t, err) + require.Equal(t, expectedDashbaord, *dash) + + dashV1 := &dashboardv1alpha1.Dashboard{ + ObjectMeta: v1.ObjectMeta{ + Name: name, + Namespace: namespace, + CreationTimestamp: v1.NewTime(creationTimestamp), + Annotations: annotations, + Labels: labels, + ResourceVersion: rv, + }, + Spec: dashboardv1alpha1.DashboardSpec{ + Title: title, + Unstructured: common.Unstructured{Object: body}, + }, + } + dash, err = ToInternalDashboard(scheme, dashV1) + require.NoError(t, err) + require.Equal(t, expectedDashbaord, *dash) + + dashV2 := &dashboardv2alpha1.Dashboard{ + ObjectMeta: v1.ObjectMeta{ + Name: name, + Namespace: namespace, + CreationTimestamp: v1.NewTime(creationTimestamp), + Annotations: annotations, + Labels: labels, + ResourceVersion: rv, + }, + Spec: dashboardv2alpha1.DashboardSpec{ + Title: title, + Unstructured: common.Unstructured{Object: body}, + }, + } + dash, err = ToInternalDashboard(scheme, dashV2) + require.NoError(t, err) + require.Equal(t, expectedDashbaord, *dash) +} diff --git a/pkg/registry/apis/dashboard/large.go b/pkg/registry/apis/dashboard/large.go index 0b710de4f4a..88a5eb2d56d 100644 --- a/pkg/registry/apis/dashboard/large.go +++ b/pkg/registry/apis/dashboard/large.go @@ -7,11 +7,11 @@ import ( "k8s.io/apimachinery/pkg/runtime" commonV0 "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" - dashboard "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1" + dashboard "github.com/grafana/grafana/pkg/apis/dashboard" "github.com/grafana/grafana/pkg/storage/unified/apistore" ) -func newDashboardLargeObjectSupport() *apistore.BasicLargeObjectSupport { +func NewDashboardLargeObjectSupport(scheme *runtime.Scheme) *apistore.BasicLargeObjectSupport { return &apistore.BasicLargeObjectSupport{ TheGroupResource: dashboard.DashboardResourceInfo.GroupResource(), @@ -22,9 +22,9 @@ func newDashboardLargeObjectSupport() *apistore.BasicLargeObjectSupport { MaxByteSize: 10 * 1024 * 1024, ReduceSpec: func(obj runtime.Object) error { - dash, ok := obj.(*dashboard.Dashboard) - if !ok { - return fmt.Errorf("expected dashboard") + dash, err := ToInternalDashboard(scheme, obj) + if err != nil { + return err } old := dash.Spec.Object spec := commonV0.Unstructured{Object: make(map[string]any)} @@ -38,13 +38,18 @@ func newDashboardLargeObjectSupport() *apistore.BasicLargeObjectSupport { spec.Object[k] = v } } + + if err := scheme.Convert(dash, obj, nil); err != nil { + return fmt.Errorf("failed to update original object: %w", err) + } + return nil }, RebuildSpec: func(obj runtime.Object, blob []byte) error { - dash, ok := obj.(*dashboard.Dashboard) - if !ok { - return fmt.Errorf("expected dashboard") + dash, err := ToInternalDashboard(scheme, obj) + if err != nil { + return err } return json.Unmarshal(blob, &dash.Spec) }, diff --git a/pkg/registry/apis/dashboard/large_test.go b/pkg/registry/apis/dashboard/large_test.go index ff469863ec5..a1f1094a935 100644 --- a/pkg/registry/apis/dashboard/large_test.go +++ b/pkg/registry/apis/dashboard/large_test.go @@ -5,11 +5,12 @@ import ( "os" "testing" + dashboardinternal "github.com/grafana/grafana/pkg/apis/dashboard" + dashboardv0alpha1 "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1" "github.com/stretchr/testify/require" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - - dashboard "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1" + "k8s.io/apimachinery/pkg/runtime" ) func TestLargeDashboardSupport(t *testing.T) { @@ -20,7 +21,7 @@ func TestLargeDashboardSupport(t *testing.T) { f, err := os.ReadFile(devdash) require.NoError(t, err) - dash := &dashboard.Dashboard{ + dash := &dashboardv0alpha1.Dashboard{ ObjectMeta: v1.ObjectMeta{ Name: "test", Namespace: "test", @@ -35,7 +36,15 @@ func TestLargeDashboardSupport(t *testing.T) { require.True(t, found) require.Len(t, panels, expectedPanelCount) - largeObject := newDashboardLargeObjectSupport() + scheme := runtime.NewScheme() + + err = dashboardv0alpha1.AddToScheme(scheme) + require.NoError(t, err) + + err = dashboardinternal.AddToScheme(scheme) + require.NoError(t, err) + + largeObject := NewDashboardLargeObjectSupport(scheme) // Convert the dashboard to a small value err = largeObject.ReduceSpec(dash) diff --git a/pkg/registry/apis/dashboard/legacy/sql_dashboards.go b/pkg/registry/apis/dashboard/legacy/sql_dashboards.go index b0c38b8f24a..b91d11cc414 100644 --- a/pkg/registry/apis/dashboard/legacy/sql_dashboards.go +++ b/pkg/registry/apis/dashboard/legacy/sql_dashboards.go @@ -18,7 +18,7 @@ import ( "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" "github.com/grafana/grafana/pkg/apimachinery/identity" "github.com/grafana/grafana/pkg/apimachinery/utils" - dashboardsV0 "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1" + dashboard "github.com/grafana/grafana/pkg/apis/dashboard" "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/services/apiserver/endpoints/request" gapiutil "github.com/grafana/grafana/pkg/services/apiserver/utils" @@ -38,7 +38,7 @@ type dashboardRow struct { RV int64 // Dashboard resource - Dash *dashboardsV0.Dashboard + Dash *dashboard.Dashboard // The folder UID (needed for access control checks) FolderUID string @@ -213,8 +213,8 @@ func (r *rowsWrapper) Value() []byte { } func (a *dashboardSqlAccess) scanRow(rows *sql.Rows) (*dashboardRow, error) { - dash := &dashboardsV0.Dashboard{ - TypeMeta: dashboardsV0.DashboardResourceInfo.TypeMeta(), + dash := &dashboard.Dashboard{ + TypeMeta: dashboard.DashboardResourceInfo.TypeMeta(), ObjectMeta: metav1.ObjectMeta{Annotations: make(map[string]string)}, } row := &dashboardRow{Dash: dash} @@ -323,7 +323,7 @@ func getUserID(v sql.NullString, id sql.NullInt64) string { } // DeleteDashboard implements DashboardAccess. -func (a *dashboardSqlAccess) DeleteDashboard(ctx context.Context, orgId int64, uid string) (*dashboardsV0.Dashboard, bool, error) { +func (a *dashboardSqlAccess) DeleteDashboard(ctx context.Context, orgId int64, uid string) (*dashboard.Dashboard, bool, error) { dash, _, err := a.GetDashboard(ctx, orgId, uid, 0) if err != nil { return nil, false, err @@ -355,7 +355,7 @@ func (a *dashboardSqlAccess) DeleteDashboard(ctx context.Context, orgId int64, u } // SaveDashboard implements DashboardAccess. -func (a *dashboardSqlAccess) SaveDashboard(ctx context.Context, orgId int64, dash *dashboardsV0.Dashboard) (*dashboardsV0.Dashboard, bool, error) { +func (a *dashboardSqlAccess) SaveDashboard(ctx context.Context, orgId int64, dash *dashboard.Dashboard) (*dashboard.Dashboard, bool, error) { created := false user, ok := claims.From(ctx) if !ok || user == nil { @@ -412,7 +412,7 @@ func (a *dashboardSqlAccess) SaveDashboard(ctx context.Context, orgId int64, das return dash, created, err } -func (a *dashboardSqlAccess) GetLibraryPanels(ctx context.Context, query LibraryPanelQuery) (*dashboardsV0.LibraryPanelList, error) { +func (a *dashboardSqlAccess) GetLibraryPanels(ctx context.Context, query LibraryPanelQuery) (*dashboard.LibraryPanelList, error) { limit := int(query.Limit) query.Limit += 1 // for continue if query.OrgID == 0 { @@ -431,7 +431,7 @@ func (a *dashboardSqlAccess) GetLibraryPanels(ctx context.Context, query Library } q := rawQuery - res := &dashboardsV0.LibraryPanelList{} + res := &dashboard.LibraryPanelList{} rows, err := sql.DB.GetSqlxSession().Query(ctx, q, req.GetArgs()...) defer func() { if rows != nil { @@ -472,16 +472,16 @@ func (a *dashboardSqlAccess) GetLibraryPanels(ctx context.Context, query Library } lastID = p.ID - item := dashboardsV0.LibraryPanel{ + item := dashboard.LibraryPanel{ ObjectMeta: metav1.ObjectMeta{ Name: p.UID, CreationTimestamp: metav1.NewTime(p.Created), ResourceVersion: strconv.FormatInt(p.Updated.UnixMilli(), 10), }, - Spec: dashboardsV0.LibraryPanelSpec{}, + Spec: dashboard.LibraryPanelSpec{}, } - status := &dashboardsV0.LibraryPanelStatus{ + status := &dashboard.LibraryPanelStatus{ Missing: v0alpha1.Unstructured{}, } err = json.Unmarshal(p.Model, &item.Spec) diff --git a/pkg/registry/apis/dashboard/legacy/storage.go b/pkg/registry/apis/dashboard/legacy/storage.go index 4a830dd2719..b6a2a9a03e8 100644 --- a/pkg/registry/apis/dashboard/legacy/storage.go +++ b/pkg/registry/apis/dashboard/legacy/storage.go @@ -11,7 +11,7 @@ import ( "github.com/grafana/authlib/claims" "github.com/grafana/grafana/pkg/apimachinery/utils" - dashboard "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1" + dashboard "github.com/grafana/grafana/pkg/apis/dashboard" "github.com/grafana/grafana/pkg/storage/unified/resource" ) diff --git a/pkg/registry/apis/dashboard/legacy/types.go b/pkg/registry/apis/dashboard/legacy/types.go index ad46cc87978..ac945e090e3 100644 --- a/pkg/registry/apis/dashboard/legacy/types.go +++ b/pkg/registry/apis/dashboard/legacy/types.go @@ -3,7 +3,7 @@ package legacy import ( "context" - dashboardsV0 "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1" + dashboard "github.com/grafana/grafana/pkg/apis/dashboard" "github.com/grafana/grafana/pkg/storage/unified/resource" ) @@ -47,10 +47,10 @@ type DashboardAccess interface { resource.StorageBackend resource.ResourceIndexServer - GetDashboard(ctx context.Context, orgId int64, uid string, version int64) (*dashboardsV0.Dashboard, int64, error) - SaveDashboard(ctx context.Context, orgId int64, dash *dashboardsV0.Dashboard) (*dashboardsV0.Dashboard, bool, error) - DeleteDashboard(ctx context.Context, orgId int64, uid string) (*dashboardsV0.Dashboard, bool, error) + GetDashboard(ctx context.Context, orgId int64, uid string, version int64) (*dashboard.Dashboard, int64, error) + SaveDashboard(ctx context.Context, orgId int64, dash *dashboard.Dashboard) (*dashboard.Dashboard, bool, error) + DeleteDashboard(ctx context.Context, orgId int64, uid string) (*dashboard.Dashboard, bool, error) // Get a typed list - GetLibraryPanels(ctx context.Context, query LibraryPanelQuery) (*dashboardsV0.LibraryPanelList, error) + GetLibraryPanels(ctx context.Context, query LibraryPanelQuery) (*dashboard.LibraryPanelList, error) } diff --git a/pkg/registry/apis/dashboard/legacy_storage.go b/pkg/registry/apis/dashboard/legacy_storage.go index c2178ca1bd7..a7f990fc2b2 100644 --- a/pkg/registry/apis/dashboard/legacy_storage.go +++ b/pkg/registry/apis/dashboard/legacy_storage.go @@ -15,19 +15,19 @@ import ( "github.com/grafana/grafana/pkg/storage/unified/resource" ) -type dashboardStorage struct { - resource utils.ResourceInfo - access legacy.DashboardAccess - tableConverter rest.TableConvertor +type DashboardStorage struct { + Resource utils.ResourceInfo + Access legacy.DashboardAccess + TableConverter rest.TableConvertor - server resource.ResourceServer - features featuremgmt.FeatureToggles + Server resource.ResourceServer + Features featuremgmt.FeatureToggles } -func (s *dashboardStorage) newStore(scheme *runtime.Scheme, defaultOptsGetter generic.RESTOptionsGetter, reg prometheus.Registerer) (grafanarest.LegacyStorage, error) { +func (s *DashboardStorage) NewStore(scheme *runtime.Scheme, defaultOptsGetter generic.RESTOptionsGetter, reg prometheus.Registerer) (grafanarest.LegacyStorage, error) { server, err := resource.NewResourceServer(resource.ResourceServerOptions{ - Backend: s.access, - Index: s.access, + Backend: s.Access, + Index: s.Access, Reg: reg, // WriteAccess: resource.WriteAccessHooks{ // Folder: func(ctx context.Context, user identity.Requester, uid string) bool { @@ -38,9 +38,9 @@ func (s *dashboardStorage) newStore(scheme *runtime.Scheme, defaultOptsGetter ge if err != nil { return nil, err } - s.server = server + s.Server = server - resourceInfo := s.resource + resourceInfo := s.Resource defaultOpts, err := defaultOptsGetter.GetRESTOptions(resourceInfo.GroupResource(), nil) if err != nil { return nil, err diff --git a/pkg/registry/apis/dashboard/libary_panel.go b/pkg/registry/apis/dashboard/libary_panel.go index c00e21a2562..a540b28ecf2 100644 --- a/pkg/registry/apis/dashboard/libary_panel.go +++ b/pkg/registry/apis/dashboard/libary_panel.go @@ -10,48 +10,47 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/registry/rest" - dashboard "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1" + "github.com/grafana/grafana/pkg/apimachinery/utils" "github.com/grafana/grafana/pkg/registry/apis/dashboard/legacy" "github.com/grafana/grafana/pkg/services/apiserver/endpoints/request" ) var ( - _ rest.Scoper = (*libraryPanelStore)(nil) - _ rest.SingularNameProvider = (*libraryPanelStore)(nil) - _ rest.Getter = (*libraryPanelStore)(nil) - _ rest.Lister = (*libraryPanelStore)(nil) - _ rest.Storage = (*libraryPanelStore)(nil) + _ rest.Scoper = (*LibraryPanelStore)(nil) + _ rest.SingularNameProvider = (*LibraryPanelStore)(nil) + _ rest.Getter = (*LibraryPanelStore)(nil) + _ rest.Lister = (*LibraryPanelStore)(nil) + _ rest.Storage = (*LibraryPanelStore)(nil) ) -var lpr = dashboard.LibraryPanelResourceInfo - -type libraryPanelStore struct { - access legacy.DashboardAccess +type LibraryPanelStore struct { + Access legacy.DashboardAccess + ResourceInfo utils.ResourceInfo } -func (s *libraryPanelStore) New() runtime.Object { - return lpr.NewFunc() +func (s *LibraryPanelStore) New() runtime.Object { + return s.ResourceInfo.NewFunc() } -func (s *libraryPanelStore) Destroy() {} +func (s *LibraryPanelStore) Destroy() {} -func (s *libraryPanelStore) NamespaceScoped() bool { +func (s *LibraryPanelStore) NamespaceScoped() bool { return true // namespace == org } -func (s *libraryPanelStore) GetSingularName() string { - return lpr.GetSingularName() +func (s *LibraryPanelStore) GetSingularName() string { + return s.ResourceInfo.GetSingularName() } -func (s *libraryPanelStore) NewList() runtime.Object { - return lpr.NewListFunc() +func (s *LibraryPanelStore) NewList() runtime.Object { + return s.ResourceInfo.NewListFunc() } -func (s *libraryPanelStore) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) { - return lpr.TableConverter().ConvertToTable(ctx, object, tableOptions) +func (s *LibraryPanelStore) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) { + return s.ResourceInfo.TableConverter().ConvertToTable(ctx, object, tableOptions) } -func (s *libraryPanelStore) List(ctx context.Context, options *internalversion.ListOptions) (runtime.Object, error) { +func (s *LibraryPanelStore) List(ctx context.Context, options *internalversion.ListOptions) (runtime.Object, error) { ns, err := request.NamespaceInfoFrom(ctx, true) if err != nil { return nil, err @@ -69,10 +68,10 @@ func (s *libraryPanelStore) List(ctx context.Context, options *internalversion.L if query.Limit < 1 { query.Limit = 25 } - return s.access.GetLibraryPanels(ctx, query) + return s.Access.GetLibraryPanels(ctx, query) } -func (s *libraryPanelStore) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { +func (s *LibraryPanelStore) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { ns, err := request.NamespaceInfoFrom(ctx, true) if err != nil { return nil, err @@ -83,12 +82,12 @@ func (s *libraryPanelStore) Get(ctx context.Context, name string, options *metav UID: name, Limit: 1, } - found, err := s.access.GetLibraryPanels(ctx, query) + found, err := s.Access.GetLibraryPanels(ctx, query) if err != nil { return nil, err } if len(found.Items) == 1 { return &found.Items[0], nil } - return nil, lpr.NewNotFound(name) + return nil, s.ResourceInfo.NewNotFound(name) } diff --git a/pkg/registry/apis/dashboard/register.go b/pkg/registry/apis/dashboard/register.go index 1e10e1e6ff8..cb97e15aa22 100644 --- a/pkg/registry/apis/dashboard/register.go +++ b/pkg/registry/apis/dashboard/register.go @@ -1,32 +1,20 @@ package dashboard import ( - "github.com/prometheus/client_golang/prometheus" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apiserver/pkg/registry/rest" + "k8s.io/apiserver/pkg/authorization/authorizer" genericapiserver "k8s.io/apiserver/pkg/server" "k8s.io/kube-openapi/pkg/common" "k8s.io/kube-openapi/pkg/spec3" - dashboard "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1" - grafanaregistry "github.com/grafana/grafana/pkg/apiserver/registry/generic" + dashboardinternal "github.com/grafana/grafana/pkg/apis/dashboard" + dashboardv0alpha1 "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1" + dashboardv1alpha1 "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1" + dashboardv2alpha1 "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1" grafanarest "github.com/grafana/grafana/pkg/apiserver/rest" - "github.com/grafana/grafana/pkg/infra/db" - "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/infra/tracing" - "github.com/grafana/grafana/pkg/registry/apis/dashboard/legacy" - "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/apiserver/builder" - "github.com/grafana/grafana/pkg/services/apiserver/endpoints/request" - "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/featuremgmt" - "github.com/grafana/grafana/pkg/services/provisioning" - "github.com/grafana/grafana/pkg/setting" - "github.com/grafana/grafana/pkg/storage/legacysql" - "github.com/grafana/grafana/pkg/storage/unified/apistore" - "github.com/grafana/grafana/pkg/storage/unified/resource" ) var ( @@ -35,171 +23,52 @@ var ( ) // This is used just so wire has something unique to return -type DashboardsAPIBuilder struct { - dashboardService dashboards.DashboardService +type DashboardsAPIBuilder struct{} - accessControl accesscontrol.AccessControl - legacy *dashboardStorage - unified resource.ResourceClient - - log log.Logger - reg prometheus.Registerer -} - -func RegisterAPIService(cfg *setting.Cfg, features featuremgmt.FeatureToggles, +func RegisterAPIService( + features featuremgmt.FeatureToggles, apiregistration builder.APIRegistrar, - dashboardService dashboards.DashboardService, - accessControl accesscontrol.AccessControl, - provisioning provisioning.ProvisioningService, - dashStore dashboards.Store, - reg prometheus.Registerer, - sql db.DB, - tracing *tracing.TracingService, - unified resource.ResourceClient, ) *DashboardsAPIBuilder { if !features.IsEnabledGlobally(featuremgmt.FlagGrafanaAPIServerWithExperimentalAPIs) && !features.IsEnabledGlobally(featuremgmt.FlagKubernetesDashboardsAPI) { return nil // skip registration unless opting into experimental apis or dashboards in the k8s api } - - softDelete := features.IsEnabledGlobally(featuremgmt.FlagDashboardRestore) - dbp := legacysql.NewDatabaseProvider(sql) - namespacer := request.GetNamespaceMapper(cfg) - builder := &DashboardsAPIBuilder{ - log: log.New("grafana-apiserver.dashboards"), - - dashboardService: dashboardService, - accessControl: accessControl, - unified: unified, - - legacy: &dashboardStorage{ - resource: dashboard.DashboardResourceInfo, - access: legacy.NewDashboardAccess(dbp, namespacer, dashStore, provisioning, softDelete), - tableConverter: dashboard.DashboardResourceInfo.TableConverter(), - features: features, - }, - reg: reg, - } + builder := &DashboardsAPIBuilder{} apiregistration.RegisterAPI(builder) return builder } func (b *DashboardsAPIBuilder) GetGroupVersion() schema.GroupVersion { - return dashboard.DashboardResourceInfo.GroupVersion() + return dashboardinternal.DashboardResourceInfo.GroupVersion() +} + +func (b *DashboardsAPIBuilder) GetAuthorizer() authorizer.Authorizer { + return nil // no authorizer } func (b *DashboardsAPIBuilder) GetDesiredDualWriterMode(dualWrite bool, modeMap map[string]grafanarest.DualWriterMode) grafanarest.DualWriterMode { - // Add required configuration support in order to enable other modes. For an example, see pkg/registry/apis/playlist/register.go return grafanarest.Mode0 } -func addKnownTypes(scheme *runtime.Scheme, gv schema.GroupVersion) { - scheme.AddKnownTypes(gv, - &dashboard.Dashboard{}, - &dashboard.DashboardList{}, - &dashboard.DashboardWithAccessInfo{}, - &dashboard.DashboardVersionList{}, - &dashboard.VersionsQueryOptions{}, - &dashboard.LibraryPanel{}, - &dashboard.LibraryPanelList{}, - &metav1.PartialObjectMetadata{}, - &metav1.PartialObjectMetadataList{}, - ) -} - func (b *DashboardsAPIBuilder) InstallSchema(scheme *runtime.Scheme) error { - resourceInfo := dashboard.DashboardResourceInfo - addKnownTypes(scheme, resourceInfo.GroupVersion()) - - // Link this version to the internal representation. - // This is used for server-side-apply (PATCH), and avoids the error: - // "no kind is registered for the type" - addKnownTypes(scheme, schema.GroupVersion{ - Group: resourceInfo.GroupVersion().Group, - Version: runtime.APIVersionInternal, - }) - - // If multiple versions exist, then register conversions from zz_generated.conversion.go - // if err := playlist.RegisterConversions(scheme); err != nil { - // return err - // } - metav1.AddToGroupVersion(scheme, resourceInfo.GroupVersion()) - return scheme.SetVersionPriority(resourceInfo.GroupVersion()) + if err := dashboardinternal.AddToScheme(scheme); err != nil { + return err + } + return scheme.SetVersionPriority( + dashboardv0alpha1.DashboardResourceInfo.GroupVersion(), + dashboardv1alpha1.DashboardResourceInfo.GroupVersion(), + dashboardv2alpha1.DashboardResourceInfo.GroupVersion(), + ) } func (b *DashboardsAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.APIGroupInfo, opts builder.APIGroupOptions) error { - scheme := opts.Scheme - - optsGetter := opts.OptsGetter - dualWriteBuilder := opts.DualWriteBuilder - dash := b.legacy.resource - legacyStore, err := b.legacy.newStore(scheme, optsGetter, b.reg) - if err != nil { - return err - } - - // Split dashboards when they are large - var largeObjects apistore.LargeObjectSupport - if b.legacy.features.IsEnabledGlobally(featuremgmt.FlagUnifiedStorageBigObjectsSupport) { - largeObjects = newDashboardLargeObjectSupport() - opts.StorageOptions(dash.GroupResource(), apistore.StorageOptions{ - LargeObjectSupport: largeObjects, - }) - } - - storage := map[string]rest.Storage{} - storage[dash.StoragePath()] = legacyStore - storage[dash.StoragePath("history")] = apistore.NewHistoryConnector( - b.legacy.server, // as client??? - dashboard.DashboardResourceInfo.GroupResource(), - ) - - // Dual writes if a RESTOptionsGetter is provided - if optsGetter != nil && dualWriteBuilder != nil { - store, err := grafanaregistry.NewRegistryStore(scheme, dash, optsGetter) - if err != nil { - return err - } - storage[dash.StoragePath()], err = dualWriteBuilder(dash.GroupResource(), legacyStore, store) - if err != nil { - return err - } - } - - // Register the DTO endpoint that will consolidate all dashboard bits - storage[dash.StoragePath("dto")], err = newDTOConnector(storage[dash.StoragePath()], largeObjects, b) - if err != nil { - return err - } - - // Expose read only library panels - storage[dashboard.LibraryPanelResourceInfo.StoragePath()] = &libraryPanelStore{ - access: b.legacy.access, - } - - apiGroupInfo.VersionedResourcesStorageMap[dashboard.VERSION] = storage return nil } func (b *DashboardsAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions { - return dashboard.GetOpenAPIDefinitions + return nil } func (b *DashboardsAPIBuilder) PostProcessOpenAPI(oas *spec3.OpenAPI) (*spec3.OpenAPI, error) { - // The plugin description - oas.Info.Description = "Grafana dashboards as resources" - - // The root api URL - root := "/apis/" + b.GetGroupVersion().String() + "/" - - // Hide the ability to list or watch across all tenants - delete(oas.Paths.Paths, root+dashboard.DashboardResourceInfo.GroupResource().Resource) - delete(oas.Paths.Paths, root+"watch/"+dashboard.DashboardResourceInfo.GroupResource().Resource) - - // The root API discovery list - sub := oas.Paths.Paths[root] - if sub != nil && sub.Get != nil { - sub.Get.Tags = []string{"API Discovery"} // sorts first in the list - } return oas, nil } diff --git a/pkg/registry/apis/dashboard/sub_dto.go b/pkg/registry/apis/dashboard/sub_dto.go index fa50ebc926c..def5d94df0e 100644 --- a/pkg/registry/apis/dashboard/sub_dto.go +++ b/pkg/registry/apis/dashboard/sub_dto.go @@ -13,7 +13,7 @@ import ( "github.com/grafana/authlib/claims" "github.com/grafana/grafana/pkg/apimachinery/identity" "github.com/grafana/grafana/pkg/apimachinery/utils" - dashboard "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1" + dashboard "github.com/grafana/grafana/pkg/apis/dashboard" "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/infra/slugify" "github.com/grafana/grafana/pkg/registry/apis/dashboard/legacy" @@ -32,17 +32,29 @@ type DTOConnector struct { unified resource.ResourceClient largeObjects apistore.LargeObjectSupport accessControl accesscontrol.AccessControl + scheme *runtime.Scheme + newFunc func() runtime.Object log log.Logger } -func newDTOConnector(dash rest.Storage, largeObjects apistore.LargeObjectSupport, builder *DashboardsAPIBuilder) (rest.Storage, error) { +func NewDTOConnector( + dash rest.Storage, + largeObjects apistore.LargeObjectSupport, + legacyAccess legacy.DashboardAccess, + resourceClient resource.ResourceClient, + accessControl accesscontrol.AccessControl, + scheme *runtime.Scheme, + newFunc func() runtime.Object, +) (rest.Storage, error) { ok := false v := &DTOConnector{ - legacy: builder.legacy.access, - accessControl: builder.accessControl, - unified: builder.unified, + legacy: legacyAccess, + accessControl: accessControl, + unified: resourceClient, largeObjects: largeObjects, - log: builder.log, + newFunc: newFunc, + scheme: scheme, + log: log.New("grafana-apiserver.dashboards.dto-connector"), } v.getter, ok = dash.(rest.Getter) if !ok { @@ -57,7 +69,7 @@ var ( ) func (r *DTOConnector) New() runtime.Object { - return &dashboard.DashboardWithAccessInfo{} + return r.newFunc() } func (r *DTOConnector) Destroy() { @@ -76,7 +88,7 @@ func (r *DTOConnector) ProducesMIMETypes(verb string) []string { } func (r *DTOConnector) ProducesObject(verb string) interface{} { - return &dashboard.DashboardWithAccessInfo{} + return r.newFunc() } func (r *DTOConnector) Connect(ctx context.Context, name string, opts runtime.Object, responder rest.Responder) (http.Handler, error) { @@ -95,10 +107,11 @@ func (r *DTOConnector) Connect(ctx context.Context, name string, opts runtime.Ob return nil, err } - dash, ok := rawobj.(*dashboard.Dashboard) - if !ok { - return nil, fmt.Errorf("expecting dashboard, not %t", rawobj) + dash, err := ToInternalDashboard(r.scheme, rawobj) + if err != nil { + return nil, err } + obj, err := utils.MetaAccessor(dash) if err != nil { return nil, err diff --git a/pkg/registry/apis/dashboard/v0alpha1/register.go b/pkg/registry/apis/dashboard/v0alpha1/register.go new file mode 100644 index 00000000000..e6b5e1f9bd9 --- /dev/null +++ b/pkg/registry/apis/dashboard/v0alpha1/register.go @@ -0,0 +1,198 @@ +package v0alpha1 + +import ( + "errors" + + "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" + + dashboardv0alpha1 "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1" + grafanaregistry "github.com/grafana/grafana/pkg/apiserver/registry/generic" + grafanarest "github.com/grafana/grafana/pkg/apiserver/rest" + "github.com/grafana/grafana/pkg/infra/db" + "github.com/grafana/grafana/pkg/infra/log" + "github.com/grafana/grafana/pkg/infra/tracing" + "github.com/grafana/grafana/pkg/registry/apis/dashboard" + "github.com/grafana/grafana/pkg/registry/apis/dashboard/legacy" + "github.com/grafana/grafana/pkg/services/accesscontrol" + "github.com/grafana/grafana/pkg/services/apiserver/builder" + "github.com/grafana/grafana/pkg/services/apiserver/endpoints/request" + "github.com/grafana/grafana/pkg/services/dashboards" + "github.com/grafana/grafana/pkg/services/featuremgmt" + "github.com/grafana/grafana/pkg/services/provisioning" + "github.com/grafana/grafana/pkg/setting" + "github.com/grafana/grafana/pkg/storage/legacysql" + "github.com/grafana/grafana/pkg/storage/unified/apistore" + "github.com/grafana/grafana/pkg/storage/unified/resource" +) + +var ( + _ builder.APIGroupBuilder = (*DashboardsAPIBuilder)(nil) + _ builder.OpenAPIPostProcessor = (*DashboardsAPIBuilder)(nil) +) + +// This is used just so wire has something unique to return +type DashboardsAPIBuilder struct { + dashboardService dashboards.DashboardService + + accessControl accesscontrol.AccessControl + legacy *dashboard.DashboardStorage + unified resource.ResourceClient + + log log.Logger + reg prometheus.Registerer +} + +func RegisterAPIService(cfg *setting.Cfg, features featuremgmt.FeatureToggles, + apiregistration builder.APIRegistrar, + dashboardService dashboards.DashboardService, + accessControl accesscontrol.AccessControl, + provisioning provisioning.ProvisioningService, + dashStore dashboards.Store, + reg prometheus.Registerer, + sql db.DB, + tracing *tracing.TracingService, + unified resource.ResourceClient, +) *DashboardsAPIBuilder { + if !features.IsEnabledGlobally(featuremgmt.FlagGrafanaAPIServerWithExperimentalAPIs) && !features.IsEnabledGlobally(featuremgmt.FlagKubernetesDashboardsAPI) { + return nil // skip registration unless opting into experimental apis or dashboards in the k8s api + } + + softDelete := features.IsEnabledGlobally(featuremgmt.FlagDashboardRestore) + dbp := legacysql.NewDatabaseProvider(sql) + namespacer := request.GetNamespaceMapper(cfg) + builder := &DashboardsAPIBuilder{ + log: log.New("grafana-apiserver.dashboards.v0alpha1"), + + dashboardService: dashboardService, + accessControl: accessControl, + unified: unified, + + legacy: &dashboard.DashboardStorage{ + Resource: dashboardv0alpha1.DashboardResourceInfo, + Access: legacy.NewDashboardAccess(dbp, namespacer, dashStore, provisioning, softDelete), + TableConverter: dashboardv0alpha1.DashboardResourceInfo.TableConverter(), + Features: features, + }, + reg: reg, + } + apiregistration.RegisterAPI(builder) + return builder +} + +func (b *DashboardsAPIBuilder) GetGroupVersion() schema.GroupVersion { + return dashboardv0alpha1.DashboardResourceInfo.GroupVersion() +} + +func (b *DashboardsAPIBuilder) GetAuthorizer() authorizer.Authorizer { + return dashboard.GetAuthorizer(b.dashboardService, b.log) +} + +func (b *DashboardsAPIBuilder) GetDesiredDualWriterMode(dualWrite bool, modeMap map[string]grafanarest.DualWriterMode) grafanarest.DualWriterMode { + // Add required configuration support in order to enable other modes. For an example, see pkg/registry/apis/playlist/register.go + return grafanarest.Mode0 +} + +func (b *DashboardsAPIBuilder) InstallSchema(scheme *runtime.Scheme) error { + return dashboardv0alpha1.AddToScheme(scheme) +} + +func (b *DashboardsAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.APIGroupInfo, opts builder.APIGroupOptions) error { + scheme := opts.Scheme + + optsGetter := opts.OptsGetter + dualWriteBuilder := opts.DualWriteBuilder + dash := b.legacy.Resource + legacyStore, err := b.legacy.NewStore(scheme, optsGetter, b.reg) + if err != nil { + return err + } + + // Split dashboards when they are large + var largeObjects apistore.LargeObjectSupport + if b.legacy.Features.IsEnabledGlobally(featuremgmt.FlagUnifiedStorageBigObjectsSupport) { + largeObjects = dashboard.NewDashboardLargeObjectSupport(scheme) + opts.StorageOptions(dash.GroupResource(), apistore.StorageOptions{ + LargeObjectSupport: largeObjects, + }) + } + + storage := map[string]rest.Storage{} + storage[dash.StoragePath()] = legacyStore + storage[dash.StoragePath("history")] = apistore.NewHistoryConnector( + b.legacy.Server, // as client??? + dashboardv0alpha1.DashboardResourceInfo.GroupResource(), + ) + + if optsGetter == nil { + return errors.New("missing RESTOptionsGetter") + } + + // Dual writes if a RESTOptionsGetter is provided + if dualWriteBuilder != nil { + store, err := grafanaregistry.NewRegistryStore(scheme, dash, optsGetter) + if err != nil { + return err + } + storage[dash.StoragePath()], err = dualWriteBuilder(dash.GroupResource(), legacyStore, store) + if err != nil { + return err + } + } + + // Register the DTO endpoint that will consolidate all dashboard bits + storage[dash.StoragePath("dto")], err = dashboard.NewDTOConnector( + storage[dash.StoragePath()], + largeObjects, + b.legacy.Access, + b.unified, + b.accessControl, + scheme, + func() runtime.Object { return &dashboardv0alpha1.DashboardWithAccessInfo{} }, + ) + if err != nil { + return err + } + + // Expose read only library panels + storage[dashboardv0alpha1.LibraryPanelResourceInfo.StoragePath()] = &dashboard.LibraryPanelStore{ + Access: b.legacy.Access, + ResourceInfo: dashboardv0alpha1.LibraryPanelResourceInfo, + } + + apiGroupInfo.VersionedResourcesStorageMap[dashboardv0alpha1.VERSION] = storage + return nil +} + +func (b *DashboardsAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions { + return dashboardv0alpha1.GetOpenAPIDefinitions +} + +func (b *DashboardsAPIBuilder) PostProcessOpenAPI(oas *spec3.OpenAPI) (*spec3.OpenAPI, error) { + // The plugin description + oas.Info.Description = "Grafana dashboards as resources" + + // The root api URL + root := "/apis/" + b.GetGroupVersion().String() + "/" + + // Hide the ability to list or watch across all tenants + delete(oas.Paths.Paths, root+dashboardv0alpha1.DashboardResourceInfo.GroupResource().Resource) + delete(oas.Paths.Paths, root+"watch/"+dashboardv0alpha1.DashboardResourceInfo.GroupResource().Resource) + + // The root API discovery list + sub := oas.Paths.Paths[root] + if sub != nil && sub.Get != nil { + sub.Get.Tags = []string{"API Discovery"} // sorts first in the list + } + return oas, nil +} + +func (b *DashboardsAPIBuilder) GetAPIRoutes() *builder.APIRoutes { + return nil // no custom API routes +} diff --git a/pkg/registry/apis/dashboard/v1alpha1/register.go b/pkg/registry/apis/dashboard/v1alpha1/register.go new file mode 100644 index 00000000000..74b0d08c684 --- /dev/null +++ b/pkg/registry/apis/dashboard/v1alpha1/register.go @@ -0,0 +1,192 @@ +package v1alpha1 + +import ( + "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" + + dashboardv1alpha1 "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1" + grafanaregistry "github.com/grafana/grafana/pkg/apiserver/registry/generic" + grafanarest "github.com/grafana/grafana/pkg/apiserver/rest" + "github.com/grafana/grafana/pkg/infra/db" + "github.com/grafana/grafana/pkg/infra/log" + "github.com/grafana/grafana/pkg/infra/tracing" + "github.com/grafana/grafana/pkg/registry/apis/dashboard" + "github.com/grafana/grafana/pkg/registry/apis/dashboard/legacy" + "github.com/grafana/grafana/pkg/services/accesscontrol" + "github.com/grafana/grafana/pkg/services/apiserver/builder" + "github.com/grafana/grafana/pkg/services/apiserver/endpoints/request" + "github.com/grafana/grafana/pkg/services/dashboards" + "github.com/grafana/grafana/pkg/services/featuremgmt" + "github.com/grafana/grafana/pkg/services/provisioning" + "github.com/grafana/grafana/pkg/setting" + "github.com/grafana/grafana/pkg/storage/legacysql" + "github.com/grafana/grafana/pkg/storage/unified/apistore" + "github.com/grafana/grafana/pkg/storage/unified/resource" +) + +var ( + _ builder.APIGroupBuilder = (*DashboardsAPIBuilder)(nil) + _ builder.OpenAPIPostProcessor = (*DashboardsAPIBuilder)(nil) +) + +// This is used just so wire has something unique to return +type DashboardsAPIBuilder struct { + dashboardService dashboards.DashboardService + + accessControl accesscontrol.AccessControl + legacy *dashboard.DashboardStorage + unified resource.ResourceClient + + log log.Logger + reg prometheus.Registerer +} + +func RegisterAPIService(cfg *setting.Cfg, features featuremgmt.FeatureToggles, + apiregistration builder.APIRegistrar, + dashboardService dashboards.DashboardService, + accessControl accesscontrol.AccessControl, + provisioning provisioning.ProvisioningService, + dashStore dashboards.Store, + reg prometheus.Registerer, + sql db.DB, + tracing *tracing.TracingService, + unified resource.ResourceClient, +) *DashboardsAPIBuilder { + if !features.IsEnabledGlobally(featuremgmt.FlagGrafanaAPIServerWithExperimentalAPIs) && !features.IsEnabledGlobally(featuremgmt.FlagKubernetesDashboardsAPI) { + return nil // skip registration unless opting into experimental apis or dashboards in the k8s api + } + + softDelete := features.IsEnabledGlobally(featuremgmt.FlagDashboardRestore) + dbp := legacysql.NewDatabaseProvider(sql) + namespacer := request.GetNamespaceMapper(cfg) + builder := &DashboardsAPIBuilder{ + log: log.New("grafana-apiserver.dashboards.v1alpha1"), + + dashboardService: dashboardService, + accessControl: accessControl, + unified: unified, + + legacy: &dashboard.DashboardStorage{ + Resource: dashboardv1alpha1.DashboardResourceInfo, + Access: legacy.NewDashboardAccess(dbp, namespacer, dashStore, provisioning, softDelete), + TableConverter: dashboardv1alpha1.DashboardResourceInfo.TableConverter(), + Features: features, + }, + reg: reg, + } + apiregistration.RegisterAPI(builder) + return builder +} + +func (b *DashboardsAPIBuilder) GetGroupVersion() schema.GroupVersion { + return dashboardv1alpha1.DashboardResourceInfo.GroupVersion() +} + +func (b *DashboardsAPIBuilder) GetAuthorizer() authorizer.Authorizer { + return dashboard.GetAuthorizer(b.dashboardService, b.log) +} + +func (b *DashboardsAPIBuilder) GetDesiredDualWriterMode(dualWrite bool, modeMap map[string]grafanarest.DualWriterMode) grafanarest.DualWriterMode { + // Add required configuration support in order to enable other modes. For an example, see pkg/registry/apis/playlist/register.go + return grafanarest.Mode0 +} + +func (b *DashboardsAPIBuilder) InstallSchema(scheme *runtime.Scheme) error { + return dashboardv1alpha1.AddToScheme(scheme) +} + +func (b *DashboardsAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.APIGroupInfo, opts builder.APIGroupOptions) error { + scheme := opts.Scheme + + optsGetter := opts.OptsGetter + dualWriteBuilder := opts.DualWriteBuilder + dash := b.legacy.Resource + legacyStore, err := b.legacy.NewStore(scheme, optsGetter, b.reg) + if err != nil { + return err + } + + // Split dashboards when they are large + var largeObjects apistore.LargeObjectSupport + if b.legacy.Features.IsEnabledGlobally(featuremgmt.FlagUnifiedStorageBigObjectsSupport) { + largeObjects = dashboard.NewDashboardLargeObjectSupport(scheme) + opts.StorageOptions(dash.GroupResource(), apistore.StorageOptions{ + LargeObjectSupport: largeObjects, + }) + } + + storage := map[string]rest.Storage{} + storage[dash.StoragePath()] = legacyStore + storage[dash.StoragePath("history")] = apistore.NewHistoryConnector( + b.legacy.Server, // as client??? + dashboardv1alpha1.DashboardResourceInfo.GroupResource(), + ) + + // Dual writes if a RESTOptionsGetter is provided + if optsGetter != nil && dualWriteBuilder != nil { + store, err := grafanaregistry.NewRegistryStore(scheme, dash, optsGetter) + if err != nil { + return err + } + storage[dash.StoragePath()], err = dualWriteBuilder(dash.GroupResource(), legacyStore, store) + if err != nil { + return err + } + } + + // Register the DTO endpoint that will consolidate all dashboard bits + storage[dash.StoragePath("dto")], err = dashboard.NewDTOConnector( + storage[dash.StoragePath()], + largeObjects, + b.legacy.Access, + b.unified, + b.accessControl, + scheme, + func() runtime.Object { return &dashboardv1alpha1.DashboardWithAccessInfo{} }, + ) + if err != nil { + return err + } + + // Expose read only library panels + storage[dashboardv1alpha1.LibraryPanelResourceInfo.StoragePath()] = &dashboard.LibraryPanelStore{ + Access: b.legacy.Access, + ResourceInfo: dashboardv1alpha1.LibraryPanelResourceInfo, + } + + apiGroupInfo.VersionedResourcesStorageMap[dashboardv1alpha1.VERSION] = storage + return nil +} + +func (b *DashboardsAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions { + return dashboardv1alpha1.GetOpenAPIDefinitions +} + +func (b *DashboardsAPIBuilder) PostProcessOpenAPI(oas *spec3.OpenAPI) (*spec3.OpenAPI, error) { + // The plugin description + oas.Info.Description = "Grafana dashboards as resources" + + // The root api URL + root := "/apis/" + b.GetGroupVersion().String() + "/" + + // Hide the ability to list or watch across all tenants + delete(oas.Paths.Paths, root+dashboardv1alpha1.DashboardResourceInfo.GroupResource().Resource) + delete(oas.Paths.Paths, root+"watch/"+dashboardv1alpha1.DashboardResourceInfo.GroupResource().Resource) + + // The root API discovery list + sub := oas.Paths.Paths[root] + if sub != nil && sub.Get != nil { + sub.Get.Tags = []string{"API Discovery"} // sorts first in the list + } + return oas, nil +} + +func (b *DashboardsAPIBuilder) GetAPIRoutes() *builder.APIRoutes { + return nil // no custom API routes +} diff --git a/pkg/registry/apis/dashboard/v2alpha1/register.go b/pkg/registry/apis/dashboard/v2alpha1/register.go new file mode 100644 index 00000000000..6195651cb0e --- /dev/null +++ b/pkg/registry/apis/dashboard/v2alpha1/register.go @@ -0,0 +1,192 @@ +package v2alpha1 + +import ( + "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" + + dashboardv2alpha1 "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1" + grafanaregistry "github.com/grafana/grafana/pkg/apiserver/registry/generic" + grafanarest "github.com/grafana/grafana/pkg/apiserver/rest" + "github.com/grafana/grafana/pkg/infra/db" + "github.com/grafana/grafana/pkg/infra/log" + "github.com/grafana/grafana/pkg/infra/tracing" + "github.com/grafana/grafana/pkg/registry/apis/dashboard" + "github.com/grafana/grafana/pkg/registry/apis/dashboard/legacy" + "github.com/grafana/grafana/pkg/services/accesscontrol" + "github.com/grafana/grafana/pkg/services/apiserver/builder" + "github.com/grafana/grafana/pkg/services/apiserver/endpoints/request" + "github.com/grafana/grafana/pkg/services/dashboards" + "github.com/grafana/grafana/pkg/services/featuremgmt" + "github.com/grafana/grafana/pkg/services/provisioning" + "github.com/grafana/grafana/pkg/setting" + "github.com/grafana/grafana/pkg/storage/legacysql" + "github.com/grafana/grafana/pkg/storage/unified/apistore" + "github.com/grafana/grafana/pkg/storage/unified/resource" +) + +var ( + _ builder.APIGroupBuilder = (*DashboardsAPIBuilder)(nil) + _ builder.OpenAPIPostProcessor = (*DashboardsAPIBuilder)(nil) +) + +// This is used just so wire has something unique to return +type DashboardsAPIBuilder struct { + dashboardService dashboards.DashboardService + + accessControl accesscontrol.AccessControl + legacy *dashboard.DashboardStorage + unified resource.ResourceClient + + log log.Logger + reg prometheus.Registerer +} + +func RegisterAPIService(cfg *setting.Cfg, features featuremgmt.FeatureToggles, + apiregistration builder.APIRegistrar, + dashboardService dashboards.DashboardService, + accessControl accesscontrol.AccessControl, + provisioning provisioning.ProvisioningService, + dashStore dashboards.Store, + reg prometheus.Registerer, + sql db.DB, + tracing *tracing.TracingService, + unified resource.ResourceClient, +) *DashboardsAPIBuilder { + if !features.IsEnabledGlobally(featuremgmt.FlagGrafanaAPIServerWithExperimentalAPIs) && !features.IsEnabledGlobally(featuremgmt.FlagKubernetesDashboardsAPI) { + return nil // skip registration unless opting into experimental apis or dashboards in the k8s api + } + + softDelete := features.IsEnabledGlobally(featuremgmt.FlagDashboardRestore) + dbp := legacysql.NewDatabaseProvider(sql) + namespacer := request.GetNamespaceMapper(cfg) + builder := &DashboardsAPIBuilder{ + log: log.New("grafana-apiserver.dashboards.v2alpha1"), + + dashboardService: dashboardService, + accessControl: accessControl, + unified: unified, + + legacy: &dashboard.DashboardStorage{ + Resource: dashboardv2alpha1.DashboardResourceInfo, + Access: legacy.NewDashboardAccess(dbp, namespacer, dashStore, provisioning, softDelete), + TableConverter: dashboardv2alpha1.DashboardResourceInfo.TableConverter(), + Features: features, + }, + reg: reg, + } + apiregistration.RegisterAPI(builder) + return builder +} + +func (b *DashboardsAPIBuilder) GetGroupVersion() schema.GroupVersion { + return dashboardv2alpha1.DashboardResourceInfo.GroupVersion() +} + +func (b *DashboardsAPIBuilder) GetAuthorizer() authorizer.Authorizer { + return dashboard.GetAuthorizer(b.dashboardService, b.log) +} + +func (b *DashboardsAPIBuilder) GetDesiredDualWriterMode(dualWrite bool, modeMap map[string]grafanarest.DualWriterMode) grafanarest.DualWriterMode { + // Add required configuration support in order to enable other modes. For an example, see pkg/registry/apis/playlist/register.go + return grafanarest.Mode0 +} + +func (b *DashboardsAPIBuilder) InstallSchema(scheme *runtime.Scheme) error { + return dashboardv2alpha1.AddToScheme(scheme) +} + +func (b *DashboardsAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.APIGroupInfo, opts builder.APIGroupOptions) error { + scheme := opts.Scheme + + optsGetter := opts.OptsGetter + dualWriteBuilder := opts.DualWriteBuilder + dash := b.legacy.Resource + legacyStore, err := b.legacy.NewStore(scheme, optsGetter, b.reg) + if err != nil { + return err + } + + // Split dashboards when they are large + var largeObjects apistore.LargeObjectSupport + if b.legacy.Features.IsEnabledGlobally(featuremgmt.FlagUnifiedStorageBigObjectsSupport) { + largeObjects = dashboard.NewDashboardLargeObjectSupport(scheme) + opts.StorageOptions(dash.GroupResource(), apistore.StorageOptions{ + LargeObjectSupport: largeObjects, + }) + } + + storage := map[string]rest.Storage{} + storage[dash.StoragePath()] = legacyStore + storage[dash.StoragePath("history")] = apistore.NewHistoryConnector( + b.legacy.Server, // as client??? + dashboardv2alpha1.DashboardResourceInfo.GroupResource(), + ) + + // Dual writes if a RESTOptionsGetter is provided + if optsGetter != nil && dualWriteBuilder != nil { + store, err := grafanaregistry.NewRegistryStore(scheme, dash, optsGetter) + if err != nil { + return err + } + storage[dash.StoragePath()], err = dualWriteBuilder(dash.GroupResource(), legacyStore, store) + if err != nil { + return err + } + } + + // Register the DTO endpoint that will consolidate all dashboard bits + storage[dash.StoragePath("dto")], err = dashboard.NewDTOConnector( + storage[dash.StoragePath()], + largeObjects, + b.legacy.Access, + b.unified, + b.accessControl, + scheme, + func() runtime.Object { return &dashboardv2alpha1.DashboardWithAccessInfo{} }, + ) + if err != nil { + return err + } + + // Expose read only library panels + storage[dashboardv2alpha1.LibraryPanelResourceInfo.StoragePath()] = &dashboard.LibraryPanelStore{ + Access: b.legacy.Access, + ResourceInfo: dashboardv2alpha1.LibraryPanelResourceInfo, + } + + apiGroupInfo.VersionedResourcesStorageMap[dashboardv2alpha1.VERSION] = storage + return nil +} + +func (b *DashboardsAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions { + return dashboardv2alpha1.GetOpenAPIDefinitions +} + +func (b *DashboardsAPIBuilder) PostProcessOpenAPI(oas *spec3.OpenAPI) (*spec3.OpenAPI, error) { + // The plugin description + oas.Info.Description = "Grafana dashboards as resources" + + // The root api URL + root := "/apis/" + b.GetGroupVersion().String() + "/" + + // Hide the ability to list or watch across all tenants + delete(oas.Paths.Paths, root+dashboardv2alpha1.DashboardResourceInfo.GroupResource().Resource) + delete(oas.Paths.Paths, root+"watch/"+dashboardv2alpha1.DashboardResourceInfo.GroupResource().Resource) + + // The root API discovery list + sub := oas.Paths.Paths[root] + if sub != nil && sub.Get != nil { + sub.Get.Tags = []string{"API Discovery"} // sorts first in the list + } + return oas, nil +} + +func (b *DashboardsAPIBuilder) GetAPIRoutes() *builder.APIRoutes { + return nil // no custom API routes +} diff --git a/pkg/registry/apis/wireset.go b/pkg/registry/apis/wireset.go index 112603f40d7..be18045bebe 100644 --- a/pkg/registry/apis/wireset.go +++ b/pkg/registry/apis/wireset.go @@ -4,7 +4,10 @@ import ( "github.com/google/wire" "github.com/grafana/grafana/pkg/registry/apis/alerting/notifications" - "github.com/grafana/grafana/pkg/registry/apis/dashboard" + dashboardinternal "github.com/grafana/grafana/pkg/registry/apis/dashboard" + dashboardv0alpha1 "github.com/grafana/grafana/pkg/registry/apis/dashboard/v0alpha1" + dashboardv1alpha1 "github.com/grafana/grafana/pkg/registry/apis/dashboard/v1alpha1" + dashboardv2alpha1 "github.com/grafana/grafana/pkg/registry/apis/dashboard/v2alpha1" "github.com/grafana/grafana/pkg/registry/apis/dashboardsnapshot" "github.com/grafana/grafana/pkg/registry/apis/datasource" "github.com/grafana/grafana/pkg/registry/apis/featuretoggle" @@ -28,7 +31,10 @@ var WireSet = wire.NewSet( datasource.ProvideDefaultPluginConfigs, // Each must be added here *and* in the ServiceSink above - dashboard.RegisterAPIService, + dashboardinternal.RegisterAPIService, + dashboardv0alpha1.RegisterAPIService, + dashboardv1alpha1.RegisterAPIService, + dashboardv2alpha1.RegisterAPIService, dashboardsnapshot.RegisterAPIService, featuretoggle.RegisterAPIService, datasource.RegisterAPIService, diff --git a/pkg/services/apiserver/service.go b/pkg/services/apiserver/service.go index 401c0baa25e..c0e416f3bc3 100644 --- a/pkg/services/apiserver/service.go +++ b/pkg/services/apiserver/service.go @@ -68,6 +68,8 @@ var ( &metav1.APIGroupList{}, &metav1.APIGroup{}, &metav1.APIResourceList{}, + &metav1.PartialObjectMetadata{}, + &metav1.PartialObjectMetadataList{}, } ) diff --git a/pkg/tests/apis/dashboard/dashboards_test.go b/pkg/tests/apis/dashboard/dashboards_test.go index b442ba3b040..75d69a742ac 100644 --- a/pkg/tests/apis/dashboard/dashboards_test.go +++ b/pkg/tests/apis/dashboard/dashboards_test.go @@ -209,9 +209,136 @@ func TestIntegrationDashboardsApp(t *testing.T) { t.Run("Check discovery client", func(t *testing.T) { disco := helper.GetGroupVersionInfoJSON("dashboard.grafana.app") - // fmt.Printf("%s", string(disco)) require.JSONEq(t, `[ + { + "freshness": "Current", + "resources": [ + { + "resource": "dashboards", + "responseKind": { + "group": "", + "kind": "Dashboard", + "version": "" + }, + "scope": "Namespaced", + "singularResource": "dashboard", + "subresources": [ + { + "responseKind": { + "group": "", + "kind": "DashboardWithAccessInfo", + "version": "" + }, + "subresource": "dto", + "verbs": [ + "get" + ] + }, + { + "responseKind": { + "group": "", + "kind": "PartialObjectMetadataList", + "version": "" + }, + "subresource": "history", + "verbs": [ + "get" + ] + } + ], + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] + }, + { + "resource": "librarypanels", + "responseKind": { + "group": "", + "kind": "LibraryPanel", + "version": "" + }, + "scope": "Namespaced", + "singularResource": "librarypanel", + "verbs": [ + "get", + "list" + ] + } + ], + "version": "v2alpha1" + }, + { + "freshness": "Current", + "resources": [ + { + "resource": "dashboards", + "responseKind": { + "group": "", + "kind": "Dashboard", + "version": "" + }, + "scope": "Namespaced", + "singularResource": "dashboard", + "subresources": [ + { + "responseKind": { + "group": "", + "kind": "DashboardWithAccessInfo", + "version": "" + }, + "subresource": "dto", + "verbs": [ + "get" + ] + }, + { + "responseKind": { + "group": "", + "kind": "PartialObjectMetadataList", + "version": "" + }, + "subresource": "history", + "verbs": [ + "get" + ] + } + ], + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] + }, + { + "resource": "librarypanels", + "responseKind": { + "group": "", + "kind": "LibraryPanel", + "version": "" + }, + "scope": "Namespaced", + "singularResource": "librarypanel", + "verbs": [ + "get", + "list" + ] + } + ], + "version": "v1alpha1" + }, { "freshness": "Current", "resources": [