Dashboards: Add apiVersion to dashboard table (#100845)

pull/85403/merge
Ryan McKinley 10 months ago committed by GitHub
parent 8a341ebcce
commit c1b48cc488
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 11
      pkg/api/dashboard.go
  2. 1
      pkg/api/dtos/dashboard.go
  3. 4
      pkg/apis/dashboard/doc.go
  4. 125
      pkg/apis/dashboard/migration/conversion/conversion.go
  5. 39
      pkg/apis/dashboard/migration/conversion/conversion_test.go
  6. 97
      pkg/apis/dashboard/register.go
  7. 139
      pkg/apis/dashboard/types.go
  8. 35
      pkg/apis/dashboard/v0alpha1/conversion.go
  9. 68
      pkg/apis/dashboard/v0alpha1/conversion_test.go
  10. 5
      pkg/apis/dashboard/v0alpha1/register.go
  11. 13
      pkg/apis/dashboard/v0alpha1/types.go
  12. 388
      pkg/apis/dashboard/v0alpha1/zz_generated.conversion.go
  13. 42
      pkg/apis/dashboard/v0alpha1/zz_generated.deepcopy.go
  14. 67
      pkg/apis/dashboard/v0alpha1/zz_generated.openapi.go
  15. 1
      pkg/apis/dashboard/v0alpha1/zz_generated.openapi_violation_exceptions.list
  16. 7
      pkg/apis/dashboard/v1alpha1/register.go
  17. 16
      pkg/apis/dashboard/v1alpha1/types.go
  18. 389
      pkg/apis/dashboard/v1alpha1/zz_generated.conversion.go
  19. 35
      pkg/apis/dashboard/v1alpha1/zz_generated.deepcopy.go
  20. 81
      pkg/apis/dashboard/v1alpha1/zz_generated.openapi.go
  21. 1
      pkg/apis/dashboard/v1alpha1/zz_generated.openapi_violation_exceptions.list
  22. 16
      pkg/apis/dashboard/v2alpha1/types.go
  23. 389
      pkg/apis/dashboard/v2alpha1/zz_generated.conversion.go
  24. 35
      pkg/apis/dashboard/v2alpha1/zz_generated.deepcopy.go
  25. 81
      pkg/apis/dashboard/v2alpha1/zz_generated.openapi.go
  26. 1
      pkg/apis/dashboard/v2alpha1/zz_generated.openapi_violation_exceptions.list
  27. 360
      pkg/apis/dashboard/zz_generated.deepcopy.go
  28. 2
      pkg/cmd/grafana-cli/commands/datamigrations/to_unified_storage.go
  29. 18
      pkg/registry/apis/dashboard/conversion.go
  30. 104
      pkg/registry/apis/dashboard/conversion_test.go
  31. 65
      pkg/registry/apis/dashboard/large.go
  32. 9
      pkg/registry/apis/dashboard/large_test.go
  33. 2
      pkg/registry/apis/dashboard/legacy/migrate.go
  34. 8
      pkg/registry/apis/dashboard/legacy/query_dashboards.sql
  35. 31
      pkg/registry/apis/dashboard/legacy/sql_dashboards.go
  36. 16
      pkg/registry/apis/dashboard/legacy/sql_dashboards_test.go
  37. 2
      pkg/registry/apis/dashboard/legacy/storage.go
  38. 4
      pkg/registry/apis/dashboard/legacy/testdata/mysql--query_dashboards-dashboard.sql
  39. 3
      pkg/registry/apis/dashboard/legacy/testdata/mysql--query_dashboards-dashboard_next_page.sql
  40. 3
      pkg/registry/apis/dashboard/legacy/testdata/mysql--query_dashboards-export_with_history.sql
  41. 4
      pkg/registry/apis/dashboard/legacy/testdata/mysql--query_dashboards-folders.sql
  42. 4
      pkg/registry/apis/dashboard/legacy/testdata/mysql--query_dashboards-history_uid.sql
  43. 3
      pkg/registry/apis/dashboard/legacy/testdata/mysql--query_dashboards-history_uid_at_version.sql
  44. 3
      pkg/registry/apis/dashboard/legacy/testdata/mysql--query_dashboards-history_uid_second_page.sql
  45. 4
      pkg/registry/apis/dashboard/legacy/testdata/postgres--query_dashboards-dashboard.sql
  46. 3
      pkg/registry/apis/dashboard/legacy/testdata/postgres--query_dashboards-dashboard_next_page.sql
  47. 3
      pkg/registry/apis/dashboard/legacy/testdata/postgres--query_dashboards-export_with_history.sql
  48. 4
      pkg/registry/apis/dashboard/legacy/testdata/postgres--query_dashboards-folders.sql
  49. 4
      pkg/registry/apis/dashboard/legacy/testdata/postgres--query_dashboards-history_uid.sql
  50. 3
      pkg/registry/apis/dashboard/legacy/testdata/postgres--query_dashboards-history_uid_at_version.sql
  51. 3
      pkg/registry/apis/dashboard/legacy/testdata/postgres--query_dashboards-history_uid_second_page.sql
  52. 4
      pkg/registry/apis/dashboard/legacy/testdata/sqlite--query_dashboards-dashboard.sql
  53. 3
      pkg/registry/apis/dashboard/legacy/testdata/sqlite--query_dashboards-dashboard_next_page.sql
  54. 3
      pkg/registry/apis/dashboard/legacy/testdata/sqlite--query_dashboards-export_with_history.sql
  55. 4
      pkg/registry/apis/dashboard/legacy/testdata/sqlite--query_dashboards-folders.sql
  56. 4
      pkg/registry/apis/dashboard/legacy/testdata/sqlite--query_dashboards-history_uid.sql
  57. 3
      pkg/registry/apis/dashboard/legacy/testdata/sqlite--query_dashboards-history_uid_at_version.sql
  58. 3
      pkg/registry/apis/dashboard/legacy/testdata/sqlite--query_dashboards-history_uid_second_page.sql
  59. 2
      pkg/registry/apis/dashboard/legacy/types.go
  60. 16
      pkg/registry/apis/dashboard/legacy_storage.go
  61. 14
      pkg/registry/apis/dashboard/legacysearcher/search_client.go
  62. 9
      pkg/registry/apis/dashboard/legacysearcher/search_client_test.go
  63. 54
      pkg/registry/apis/dashboard/mutate.go
  64. 192
      pkg/registry/apis/dashboard/register.go
  65. 7
      pkg/registry/apis/dashboard/search.go
  66. 144
      pkg/registry/apis/dashboard/sub_dto.go
  67. 1
      pkg/services/dashboards/database/database.go
  68. 18
      pkg/services/dashboards/models.go
  69. 19
      pkg/services/dashboards/service/dashboard_service.go
  70. 11
      pkg/services/dashboardversion/model.go
  71. 2
      pkg/services/provisioning/dashboards/dashboard.go
  72. 7
      pkg/services/sqlstore/migrations/dashboard_mig.go
  73. 4
      pkg/services/sqlstore/migrations/dashboard_version_mig.go
  74. 2
      pkg/storage/legacysql/dualwrite/utils.go
  75. 7
      pkg/storage/unified/resource/search.go
  76. 98
      pkg/tests/apis/dashboard/dashboards_test.go
  77. 4
      pkg/tests/apis/dashboard/testdata/dashboard-test-v0.yaml
  78. 6
      pkg/tests/apis/dashboard/testdata/dashboard-test-v1.yaml
  79. 6
      pkg/tests/apis/dashboard/testdata/dashboard-test-v2.yaml
  80. 7
      pkg/tests/apis/helper.go
  81. 54
      pkg/tests/apis/openapi_snapshots/dashboard.grafana.app-v0alpha1.json
  82. 3
      public/api-merged.json
  83. 1
      public/app/features/migrate-to-cloud/api/endpoints.gen.ts
  84. 3
      public/openapi3.json

@ -99,6 +99,16 @@ func (hs *HTTPServer) GetDashboard(c *contextmodel.ReqContext) response.Response
return rsp
}
// V2 values should be read from the k8s API
if strings.HasPrefix(dash.APIVersion, "v2") {
root := hs.Cfg.AppSubURL
if !strings.HasSuffix(root, "/") {
root += "/"
}
url := fmt.Sprintf("%sapis/dashboard.grafana.app/%s/namespaces/%s/dashboards/%s", root, dash.APIVersion, hs.namespacer(c.OrgID), dash.UID)
return response.Redirect(url)
}
var (
publicDashboardEnabled = false
err error
@ -182,6 +192,7 @@ func (hs *HTTPServer) GetDashboard(c *contextmodel.ReqContext) response.Response
UpdatedBy: updater,
CreatedBy: creator,
Version: dash.Version,
APIVersion: dash.APIVersion,
HasACL: dash.HasACL,
IsFolder: dash.IsFolder,
FolderId: dash.FolderID, // nolint:staticcheck

@ -26,6 +26,7 @@ type DashboardMeta struct {
Version int `json:"version"`
HasACL bool `json:"hasAcl" xorm:"has_acl"`
IsFolder bool `json:"isFolder"`
APIVersion string `json:"apiVersion,omitempty"` // v0alpha1, v1, v2beta1 etc -- the version things were *saved* at
// Deprecated: use FolderUID instead
FolderId int64 `json:"folderId"`
FolderUid string `json:"folderUid"`

@ -1,4 +0,0 @@
// +k8s:deepcopy-gen=package
// +groupName=dashboard.grafana.app
package dashboard // import "github.com/grafana/grafana/pkg/apis/dashboard"

@ -0,0 +1,125 @@
package conversion
import (
"k8s.io/apimachinery/pkg/conversion"
"k8s.io/apimachinery/pkg/runtime"
"github.com/grafana/grafana/pkg/apis/dashboard/migration"
"github.com/grafana/grafana/pkg/apis/dashboard/migration/schemaversion"
dashboardV0 "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1"
dashboardV1 "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1"
dashboardV2 "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1"
)
func RegisterConversions(s *runtime.Scheme) error {
if err := s.AddConversionFunc((*dashboardV0.Dashboard)(nil), (*dashboardV1.Dashboard)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_V0_to_V1(a.(*dashboardV0.Dashboard), b.(*dashboardV1.Dashboard), scope)
}); err != nil {
return err
}
if err := s.AddConversionFunc((*dashboardV0.Dashboard)(nil), (*dashboardV2.Dashboard)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_V0_to_V2(a.(*dashboardV0.Dashboard), b.(*dashboardV2.Dashboard), scope)
}); err != nil {
return err
}
if err := s.AddConversionFunc((*dashboardV1.Dashboard)(nil), (*dashboardV0.Dashboard)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_V1_to_V0(a.(*dashboardV1.Dashboard), b.(*dashboardV0.Dashboard), scope)
}); err != nil {
return err
}
if err := s.AddConversionFunc((*dashboardV1.Dashboard)(nil), (*dashboardV2.Dashboard)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_V1_to_V2(a.(*dashboardV1.Dashboard), b.(*dashboardV2.Dashboard), scope)
}); err != nil {
return err
}
if err := s.AddConversionFunc((*dashboardV2.Dashboard)(nil), (*dashboardV0.Dashboard)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_V2_to_V0(a.(*dashboardV2.Dashboard), b.(*dashboardV0.Dashboard), scope)
}); err != nil {
return err
}
if err := s.AddConversionFunc((*dashboardV2.Dashboard)(nil), (*dashboardV1.Dashboard)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_V2_to_V1(a.(*dashboardV2.Dashboard), b.(*dashboardV1.Dashboard), scope)
}); err != nil {
return err
}
return nil
}
func Convert_V0_to_V1(in *dashboardV0.Dashboard, out *dashboardV1.Dashboard, scope conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
out.Spec = in.Spec
out.Status = &dashboardV1.DashboardStatus{
ConversionStatus: &dashboardV1.ConversionStatus{
StoredVersion: dashboardV0.VERSION,
},
}
err := migration.Migrate(out.Spec.Object, schemaversion.LATEST_VERSION)
if err != nil {
out.Status.ConversionStatus.Failed = true
out.Status.ConversionStatus.Error = err.Error()
}
return nil
}
func Convert_V0_to_V2(in *dashboardV0.Dashboard, out *dashboardV2.Dashboard, scope conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
out.Spec = in.Spec
out.Status = &dashboardV2.DashboardStatus{
ConversionStatus: &dashboardV2.ConversionStatus{
StoredVersion: dashboardV0.VERSION,
Failed: true,
Error: "backend conversion not yet implemented",
},
}
return nil
}
func Convert_V1_to_V0(in *dashboardV1.Dashboard, out *dashboardV0.Dashboard, scope conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
out.Spec = in.Spec
out.Status = &dashboardV0.DashboardStatus{
ConversionStatus: &dashboardV0.ConversionStatus{
StoredVersion: dashboardV1.VERSION,
},
}
return nil
}
func Convert_V1_to_V2(in *dashboardV1.Dashboard, out *dashboardV2.Dashboard, scope conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
out.Spec = in.Spec
out.Status = &dashboardV2.DashboardStatus{
ConversionStatus: &dashboardV2.ConversionStatus{
StoredVersion: dashboardV1.VERSION,
Failed: true,
Error: "backend conversion not yet implemented",
},
}
return nil
}
func Convert_V2_to_V0(in *dashboardV2.Dashboard, out *dashboardV0.Dashboard, scope conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
out.Spec = in.Spec
out.Status = &dashboardV0.DashboardStatus{
ConversionStatus: &dashboardV0.ConversionStatus{
StoredVersion: dashboardV2.VERSION,
Failed: true,
Error: "backend conversion not yet implemented",
},
}
return nil
}
func Convert_V2_to_V1(in *dashboardV2.Dashboard, out *dashboardV1.Dashboard, scope conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
out.Spec = in.Spec
out.Status = &dashboardV1.DashboardStatus{
ConversionStatus: &dashboardV1.ConversionStatus{
StoredVersion: dashboardV2.VERSION,
Failed: true,
Error: "backend conversion not yet implemented",
},
}
return nil
}

@ -0,0 +1,39 @@
package conversion
import (
"fmt"
"testing"
"github.com/stretchr/testify/require"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
dashboardV0 "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1"
dashboardV1 "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1"
dashboardV2 "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1"
)
func TestConversionMatrixExist(t *testing.T) {
versions := []v1.Object{
&dashboardV0.Dashboard{},
&dashboardV1.Dashboard{},
&dashboardV2.Dashboard{},
}
scheme := runtime.NewScheme()
err := RegisterConversions(scheme)
require.NoError(t, err)
for idx, in := range versions {
kind := fmt.Sprintf("%T", in)[1:]
t.Run(kind, func(t *testing.T) {
for i, out := range versions {
if i == idx {
continue // skip the same version
}
err = scheme.Convert(in, out, nil)
require.NoError(t, err)
}
})
}
}

@ -1,97 +0,0 @@
package dashboard
import (
"fmt"
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"github.com/grafana/grafana/pkg/apimachinery/utils"
)
const (
GROUP = "dashboard.grafana.app"
VERSION = runtime.APIVersionInternal
APIVERSION = GROUP + "/" + VERSION
// Resource constants
DASHBOARD_RESOURCE = "dashboards"
LIBRARY_PANEL_RESOURCE = "librarypanels"
)
var DashboardResourceInfo = utils.NewResourceInfo(GROUP, VERSION,
DASHBOARD_RESOURCE, "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,
LIBRARY_PANEL_RESOURCE, "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
}

@ -1,144 +1,5 @@
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 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

@ -1,35 +0,0 @@
package v0alpha1
import (
conversion "k8s.io/apimachinery/pkg/conversion"
klog "k8s.io/klog/v2"
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
dashboard "github.com/grafana/grafana/pkg/apis/dashboard"
"github.com/grafana/grafana/pkg/apis/dashboard/migration"
"github.com/grafana/grafana/pkg/apis/dashboard/migration/schemaversion"
)
func Convert_dashboard_DashboardSpec_To_v0alpha1_Unstructured(in *dashboard.DashboardSpec, out *common.Unstructured, s conversion.Scope) error {
*out = in.Unstructured
if in.Title != "" {
out.Object["title"] = in.Title
}
return nil
}
func Convert_v0alpha1_Unstructured_To_dashboard_DashboardSpec(in *common.Unstructured, out *dashboard.DashboardSpec, s conversion.Scope) error {
out.Unstructured = *in
err := migration.Migrate(out.Unstructured.Object, schemaversion.LATEST_VERSION)
if err != nil {
return err
}
t, ok := out.Object["title"].(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 = t
return nil
}

@ -1,68 +0,0 @@
package v0alpha1
import (
"encoding/json"
"testing"
"github.com/stretchr/testify/require"
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
"github.com/grafana/grafana/pkg/apis/dashboard"
)
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"
}
]
},
"refresh": true,
"description": "",
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"id": 11711,
"links": [],
"panels": [],
"preload": false,
"schemaVersion": 39,
"tags": [],
"templating": {
"list": []
},
"timepicker": {},
"timezone": "utc",
"title": "New",
"uid": "be3ymutzclgqod",
"version": 1,
"weekStart": ""
}`)
object := common.Unstructured{}
err := json.Unmarshal(dashboardV0Spec, &object.Object)
require.NoError(t, err)
in := dashboard.DashboardSpec{Title: "New dashboard", Unstructured: object}
result := common.Unstructured{}
err = Convert_dashboard_DashboardSpec_To_v0alpha1_Unstructured(&in, &result, nil)
require.NoError(t, err)
// now convert back & ensure it is the same
object2 := *(result.DeepCopy())
result2 := dashboard.DashboardSpec{}
err = Convert_v0alpha1_Unstructured_To_dashboard_DashboardSpec(&object2, &result2, nil)
require.NoError(t, err)
require.Equal(t, result2.Title, "New dashboard")
require.Equal(t, result2.Unstructured.Object["schemaVersion"], 41, "schemaVersion migration not applied.")
require.Equal(t, result2.Unstructured.Object["refresh"], "", "schemaVersion migration not applied. refresh should be an empty string")
}

@ -14,8 +14,11 @@ import (
const (
GROUP = "dashboard.grafana.app"
VERSION = "v0alpha1"
RESOURCE = "dashboards"
APIVERSION = GROUP + "/" + VERSION
// Resource constants
DASHBOARD_RESOURCE = "dashboards"
LIBRARY_PANEL_RESOURCE = "librarypanels"
)
var DashboardResourceInfo = utils.NewResourceInfo(GROUP, VERSION,

@ -17,6 +17,19 @@ type Dashboard struct {
// The dashboard body (unstructured for now)
Spec common.Unstructured `json:"spec"`
// Optional dashboard status
Status *DashboardStatus `json:"status,omitempty"`
}
type DashboardStatus struct {
ConversionStatus *ConversionStatus `json:"conversion,omitempty"`
}
type ConversionStatus struct {
Failed bool `json:"failed,omitempty"`
StoredVersion string `json:"storedVersion,omitempty"`
Error string `json:"error,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

@ -11,8 +11,6 @@ import (
url "net/url"
unsafe "unsafe"
datav0alpha1 "github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1"
commonv0alpha1 "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"
@ -45,16 +43,6 @@ func RegisterConversions(s *runtime.Scheme) error {
}); 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 {
@ -65,111 +53,11 @@ func RegisterConversions(s *runtime.Scheme) error {
}); 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
}
if err := s.AddConversionFunc((*dashboard.DashboardSpec)(nil), (*commonv0alpha1.Unstructured)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_dashboard_DashboardSpec_To_v0alpha1_Unstructured(a.(*dashboard.DashboardSpec), b.(*commonv0alpha1.Unstructured), scope)
}); err != nil {
return err
}
if err := s.AddConversionFunc((*commonv0alpha1.Unstructured)(nil), (*dashboard.DashboardSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v0alpha1_Unstructured_To_dashboard_DashboardSpec(a.(*commonv0alpha1.Unstructured), b.(*dashboard.DashboardSpec), scope)
}); err != nil {
return err
}
return nil
}
@ -227,32 +115,6 @@ func Convert_dashboard_AnnotationPermission_To_v0alpha1_AnnotationPermission(in
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
if err := Convert_v0alpha1_Unstructured_To_dashboard_DashboardSpec(&in.Spec, &out.Spec, s); err != nil {
return err
}
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
if err := Convert_dashboard_DashboardSpec_To_v0alpha1_Unstructured(&in.Spec, &out.Spec, s); err != nil {
return err
}
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
@ -287,256 +149,6 @@ func Convert_dashboard_DashboardAccess_To_v0alpha1_DashboardAccess(in *dashboard
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
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]dashboard.Dashboard, len(*in))
for i := range *in {
if err := Convert_v0alpha1_Dashboard_To_dashboard_Dashboard(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.Items = nil
}
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
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_v0alpha1_Dashboard(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.Items = nil
}
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.

@ -46,12 +46,33 @@ func (in *AnnotationPermission) DeepCopy() *AnnotationPermission {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ConversionStatus) DeepCopyInto(out *ConversionStatus) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConversionStatus.
func (in *ConversionStatus) DeepCopy() *ConversionStatus {
if in == nil {
return nil
}
out := new(ConversionStatus)
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)
if in.Status != nil {
in, out := &in.Status, &out.Status
*out = new(DashboardStatus)
(*in).DeepCopyInto(*out)
}
return
}
@ -156,6 +177,27 @@ func (in *DashboardList) DeepCopyObject() runtime.Object {
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *DashboardStatus) DeepCopyInto(out *DashboardStatus) {
*out = *in
if in.ConversionStatus != nil {
in, out := &in.ConversionStatus, &out.ConversionStatus
*out = new(ConversionStatus)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardStatus.
func (in *DashboardStatus) DeepCopy() *DashboardStatus {
if in == nil {
return nil
}
out := new(DashboardStatus)
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

@ -16,10 +16,12 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
return map[string]common.OpenAPIDefinition{
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.AnnotationActions": schema_pkg_apis_dashboard_v0alpha1_AnnotationActions(ref),
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.AnnotationPermission": schema_pkg_apis_dashboard_v0alpha1_AnnotationPermission(ref),
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.ConversionStatus": schema_pkg_apis_dashboard_v0alpha1_ConversionStatus(ref),
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.Dashboard": schema_pkg_apis_dashboard_v0alpha1_Dashboard(ref),
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardAccess": schema_pkg_apis_dashboard_v0alpha1_DashboardAccess(ref),
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardHit": schema_pkg_apis_dashboard_v0alpha1_DashboardHit(ref),
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardList": schema_pkg_apis_dashboard_v0alpha1_DashboardList(ref),
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardStatus": schema_pkg_apis_dashboard_v0alpha1_DashboardStatus(ref),
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardVersionInfo": schema_pkg_apis_dashboard_v0alpha1_DashboardVersionInfo(ref),
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardVersionList": schema_pkg_apis_dashboard_v0alpha1_DashboardVersionList(ref),
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardWithAccessInfo": schema_pkg_apis_dashboard_v0alpha1_DashboardWithAccessInfo(ref),
@ -98,6 +100,36 @@ func schema_pkg_apis_dashboard_v0alpha1_AnnotationPermission(ref common.Referenc
}
}
func schema_pkg_apis_dashboard_v0alpha1_ConversionStatus(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{"object"},
Properties: map[string]spec.Schema{
"failed": {
SchemaProps: spec.SchemaProps{
Type: []string{"boolean"},
Format: "",
},
},
"storedVersion": {
SchemaProps: spec.SchemaProps{
Type: []string{"string"},
Format: "",
},
},
"error": {
SchemaProps: spec.SchemaProps{
Type: []string{"string"},
Format: "",
},
},
},
},
},
}
}
func schema_pkg_apis_dashboard_v0alpha1_Dashboard(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
@ -131,12 +163,18 @@ func schema_pkg_apis_dashboard_v0alpha1_Dashboard(ref common.ReferenceCallback)
Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured"),
},
},
"status": {
SchemaProps: spec.SchemaProps{
Description: "Optional dashboard status",
Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardStatus"),
},
},
},
Required: []string{"spec"},
},
},
Dependencies: []string{
"github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
"github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured", "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
}
}
@ -337,6 +375,25 @@ func schema_pkg_apis_dashboard_v0alpha1_DashboardList(ref common.ReferenceCallba
}
}
func schema_pkg_apis_dashboard_v0alpha1_DashboardStatus(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{"object"},
Properties: map[string]spec.Schema{
"conversion": {
SchemaProps: spec.SchemaProps{
Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.ConversionStatus"),
},
},
},
},
},
Dependencies: []string{
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.ConversionStatus"},
}
}
func schema_pkg_apis_dashboard_v0alpha1_DashboardVersionInfo(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
@ -468,6 +525,12 @@ func schema_pkg_apis_dashboard_v0alpha1_DashboardWithAccessInfo(ref common.Refer
Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured"),
},
},
"status": {
SchemaProps: spec.SchemaProps{
Description: "Optional dashboard status",
Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardStatus"),
},
},
"access": {
SchemaProps: spec.SchemaProps{
Default: map[string]interface{}{},
@ -479,7 +542,7 @@ func schema_pkg_apis_dashboard_v0alpha1_DashboardWithAccessInfo(ref common.Refer
},
},
Dependencies: []string{
"github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured", "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardAccess", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
"github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured", "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardAccess", "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
}
}

@ -3,5 +3,6 @@ API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashbo
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1,LibraryPanelStatus,Warnings
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1,SearchResults,Hits
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1,SortableFields,Fields
API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1,DashboardStatus,ConversionStatus
API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1,SortBy,Descending
API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1,SortableField,Field

@ -4,16 +4,21 @@ 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"
"github.com/grafana/grafana/pkg/apimachinery/utils"
)
const (
GROUP = "dashboard.grafana.app"
VERSION = "v1alpha1"
APIVERSION = GROUP + "/" + VERSION
// Resource constants
DASHBOARD_RESOURCE = "dashboards"
LIBRARY_PANEL_RESOURCE = "librarypanels"
)
var DashboardResourceInfo = utils.NewResourceInfo(GROUP, VERSION,

@ -16,12 +16,20 @@ type Dashboard struct {
metav1.ObjectMeta `json:"metadata,omitempty"`
// The dashboard body (unstructured for now)
Spec DashboardSpec `json:"spec"`
Spec common.Unstructured `json:"spec"`
// Optional dashboard status
Status *DashboardStatus `json:"status,omitempty"`
}
type DashboardStatus struct {
ConversionStatus *ConversionStatus `json:"conversion,omitempty"`
}
type DashboardSpec struct {
Title string `json:"title"`
common.Unstructured `json:",inline"`
type ConversionStatus struct {
Failed bool `json:"failed,omitempty"`
StoredVersion string `json:"storedVersion,omitempty"`
Error string `json:"error,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

@ -11,7 +11,6 @@ import (
url "net/url"
unsafe "unsafe"
v0alpha1 "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"
@ -44,16 +43,6 @@ func RegisterConversions(s *runtime.Scheme) error {
}); 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 {
@ -64,106 +53,6 @@ func RegisterConversions(s *runtime.Scheme) error {
}); 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((*DashboardSpec)(nil), (*dashboard.DashboardSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha1_DashboardSpec_To_dashboard_DashboardSpec(a.(*DashboardSpec), b.(*dashboard.DashboardSpec), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*dashboard.DashboardSpec)(nil), (*DashboardSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_dashboard_DashboardSpec_To_v1alpha1_DashboardSpec(a.(*dashboard.DashboardSpec), b.(*DashboardSpec), 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 {
@ -226,32 +115,6 @@ func Convert_dashboard_AnnotationPermission_To_v1alpha1_AnnotationPermission(in
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_dashboard_DashboardSpec(&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_dashboard_DashboardSpec_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
@ -286,258 +149,6 @@ func Convert_dashboard_DashboardAccess_To_v1alpha1_DashboardAccess(in *dashboard
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
out.Items = *(*[]dashboard.Dashboard)(unsafe.Pointer(&in.Items))
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
out.Items = *(*[]Dashboard)(unsafe.Pointer(&in.Items))
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_DashboardSpec_To_dashboard_DashboardSpec(in *DashboardSpec, out *dashboard.DashboardSpec, s conversion.Scope) error {
out.Title = in.Title
out.Unstructured = in.Unstructured
return nil
}
// Convert_v1alpha1_DashboardSpec_To_dashboard_DashboardSpec is an autogenerated conversion function.
func Convert_v1alpha1_DashboardSpec_To_dashboard_DashboardSpec(in *DashboardSpec, out *dashboard.DashboardSpec, s conversion.Scope) error {
return autoConvert_v1alpha1_DashboardSpec_To_dashboard_DashboardSpec(in, out, s)
}
func autoConvert_dashboard_DashboardSpec_To_v1alpha1_DashboardSpec(in *dashboard.DashboardSpec, out *DashboardSpec, s conversion.Scope) error {
out.Title = in.Title
out.Unstructured = in.Unstructured
return nil
}
// Convert_dashboard_DashboardSpec_To_v1alpha1_DashboardSpec is an autogenerated conversion function.
func Convert_dashboard_DashboardSpec_To_v1alpha1_DashboardSpec(in *dashboard.DashboardSpec, out *DashboardSpec, s conversion.Scope) error {
return autoConvert_dashboard_DashboardSpec_To_v1alpha1_DashboardSpec(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 = (*v0alpha1.DataSourceRef)(unsafe.Pointer(in.Datasource))
out.Targets = *(*[]v0alpha1.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 = (*v0alpha1.DataSourceRef)(unsafe.Pointer(in.Datasource))
out.Targets = *(*[]v0alpha1.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.

@ -46,12 +46,33 @@ func (in *AnnotationPermission) DeepCopy() *AnnotationPermission {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ConversionStatus) DeepCopyInto(out *ConversionStatus) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConversionStatus.
func (in *ConversionStatus) DeepCopy() *ConversionStatus {
if in == nil {
return nil
}
out := new(ConversionStatus)
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)
if in.Status != nil {
in, out := &in.Status, &out.Status
*out = new(DashboardStatus)
(*in).DeepCopyInto(*out)
}
return
}
@ -128,18 +149,22 @@ func (in *DashboardList) DeepCopyObject() runtime.Object {
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *DashboardSpec) DeepCopyInto(out *DashboardSpec) {
func (in *DashboardStatus) DeepCopyInto(out *DashboardStatus) {
*out = *in
in.Unstructured.DeepCopyInto(&out.Unstructured)
if in.ConversionStatus != nil {
in, out := &in.ConversionStatus, &out.ConversionStatus
*out = new(ConversionStatus)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardSpec.
func (in *DashboardSpec) DeepCopy() *DashboardSpec {
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardStatus.
func (in *DashboardStatus) DeepCopy() *DashboardStatus {
if in == nil {
return nil
}
out := new(DashboardSpec)
out := new(DashboardStatus)
in.DeepCopyInto(out)
return out
}

@ -16,10 +16,11 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
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.ConversionStatus": schema_pkg_apis_dashboard_v1alpha1_ConversionStatus(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.DashboardStatus": schema_pkg_apis_dashboard_v1alpha1_DashboardStatus(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),
@ -92,6 +93,36 @@ func schema_pkg_apis_dashboard_v1alpha1_AnnotationPermission(ref common.Referenc
}
}
func schema_pkg_apis_dashboard_v1alpha1_ConversionStatus(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{"object"},
Properties: map[string]spec.Schema{
"failed": {
SchemaProps: spec.SchemaProps{
Type: []string{"boolean"},
Format: "",
},
},
"storedVersion": {
SchemaProps: spec.SchemaProps{
Type: []string{"string"},
Format: "",
},
},
"error": {
SchemaProps: spec.SchemaProps{
Type: []string{"string"},
Format: "",
},
},
},
},
},
}
}
func schema_pkg_apis_dashboard_v1alpha1_Dashboard(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
@ -122,8 +153,13 @@ func schema_pkg_apis_dashboard_v1alpha1_Dashboard(ref common.ReferenceCallback)
"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"),
Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured"),
},
},
"status": {
SchemaProps: spec.SchemaProps{
Description: "Optional dashboard status",
Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardStatus"),
},
},
},
@ -131,7 +167,7 @@ func schema_pkg_apis_dashboard_v1alpha1_Dashboard(ref common.ReferenceCallback)
},
},
Dependencies: []string{
"github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
"github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured", "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
}
}
@ -252,38 +288,22 @@ func schema_pkg_apis_dashboard_v1alpha1_DashboardList(ref common.ReferenceCallba
}
}
func schema_pkg_apis_dashboard_v1alpha1_DashboardSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
func schema_pkg_apis_dashboard_v1alpha1_DashboardStatus(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": {
"conversion": {
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: "",
},
},
},
Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.ConversionStatus"),
},
},
},
Required: []string{"title", "Object"},
},
},
Dependencies: []string{
"github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.ConversionStatus"},
}
}
@ -415,8 +435,13 @@ func schema_pkg_apis_dashboard_v1alpha1_DashboardWithAccessInfo(ref common.Refer
"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"),
Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured"),
},
},
"status": {
SchemaProps: spec.SchemaProps{
Description: "Optional dashboard status",
Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardStatus"),
},
},
"access": {
@ -430,7 +455,7 @@ func schema_pkg_apis_dashboard_v1alpha1_DashboardWithAccessInfo(ref common.Refer
},
},
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"},
"github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured", "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardAccess", "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
}
}

@ -1 +1,2 @@
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1,LibraryPanelStatus,Warnings
API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1,DashboardStatus,ConversionStatus

@ -16,12 +16,20 @@ type Dashboard struct {
metav1.ObjectMeta `json:"metadata,omitempty"`
// The dashboard body (unstructured for now)
Spec DashboardSpec `json:"spec"`
Spec common.Unstructured `json:"spec"`
// Optional dashboard status
Status *DashboardStatus `json:"status,omitempty"`
}
type DashboardStatus struct {
ConversionStatus *ConversionStatus `json:"conversion,omitempty"`
}
type DashboardSpec struct {
Title string `json:"title"`
common.Unstructured `json:",inline"`
type ConversionStatus struct {
Failed bool `json:"failed,omitempty"`
StoredVersion string `json:"storedVersion,omitempty"`
Error string `json:"error,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

@ -11,7 +11,6 @@ import (
url "net/url"
unsafe "unsafe"
v0alpha1 "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"
@ -44,16 +43,6 @@ func RegisterConversions(s *runtime.Scheme) error {
}); 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 {
@ -64,106 +53,6 @@ func RegisterConversions(s *runtime.Scheme) error {
}); 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((*DashboardSpec)(nil), (*dashboard.DashboardSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v2alpha1_DashboardSpec_To_dashboard_DashboardSpec(a.(*DashboardSpec), b.(*dashboard.DashboardSpec), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*dashboard.DashboardSpec)(nil), (*DashboardSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_dashboard_DashboardSpec_To_v2alpha1_DashboardSpec(a.(*dashboard.DashboardSpec), b.(*DashboardSpec), 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 {
@ -226,32 +115,6 @@ func Convert_dashboard_AnnotationPermission_To_v2alpha1_AnnotationPermission(in
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_dashboard_DashboardSpec(&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_dashboard_DashboardSpec_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
@ -286,258 +149,6 @@ func Convert_dashboard_DashboardAccess_To_v2alpha1_DashboardAccess(in *dashboard
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
out.Items = *(*[]dashboard.Dashboard)(unsafe.Pointer(&in.Items))
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
out.Items = *(*[]Dashboard)(unsafe.Pointer(&in.Items))
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_DashboardSpec_To_dashboard_DashboardSpec(in *DashboardSpec, out *dashboard.DashboardSpec, s conversion.Scope) error {
out.Title = in.Title
out.Unstructured = in.Unstructured
return nil
}
// Convert_v2alpha1_DashboardSpec_To_dashboard_DashboardSpec is an autogenerated conversion function.
func Convert_v2alpha1_DashboardSpec_To_dashboard_DashboardSpec(in *DashboardSpec, out *dashboard.DashboardSpec, s conversion.Scope) error {
return autoConvert_v2alpha1_DashboardSpec_To_dashboard_DashboardSpec(in, out, s)
}
func autoConvert_dashboard_DashboardSpec_To_v2alpha1_DashboardSpec(in *dashboard.DashboardSpec, out *DashboardSpec, s conversion.Scope) error {
out.Title = in.Title
out.Unstructured = in.Unstructured
return nil
}
// Convert_dashboard_DashboardSpec_To_v2alpha1_DashboardSpec is an autogenerated conversion function.
func Convert_dashboard_DashboardSpec_To_v2alpha1_DashboardSpec(in *dashboard.DashboardSpec, out *DashboardSpec, s conversion.Scope) error {
return autoConvert_dashboard_DashboardSpec_To_v2alpha1_DashboardSpec(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 = (*v0alpha1.DataSourceRef)(unsafe.Pointer(in.Datasource))
out.Targets = *(*[]v0alpha1.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 = (*v0alpha1.DataSourceRef)(unsafe.Pointer(in.Datasource))
out.Targets = *(*[]v0alpha1.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.

@ -46,12 +46,33 @@ func (in *AnnotationPermission) DeepCopy() *AnnotationPermission {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ConversionStatus) DeepCopyInto(out *ConversionStatus) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConversionStatus.
func (in *ConversionStatus) DeepCopy() *ConversionStatus {
if in == nil {
return nil
}
out := new(ConversionStatus)
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)
if in.Status != nil {
in, out := &in.Status, &out.Status
*out = new(DashboardStatus)
(*in).DeepCopyInto(*out)
}
return
}
@ -128,18 +149,22 @@ func (in *DashboardList) DeepCopyObject() runtime.Object {
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *DashboardSpec) DeepCopyInto(out *DashboardSpec) {
func (in *DashboardStatus) DeepCopyInto(out *DashboardStatus) {
*out = *in
in.Unstructured.DeepCopyInto(&out.Unstructured)
if in.ConversionStatus != nil {
in, out := &in.ConversionStatus, &out.ConversionStatus
*out = new(ConversionStatus)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardSpec.
func (in *DashboardSpec) DeepCopy() *DashboardSpec {
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardStatus.
func (in *DashboardStatus) DeepCopy() *DashboardStatus {
if in == nil {
return nil
}
out := new(DashboardSpec)
out := new(DashboardStatus)
in.DeepCopyInto(out)
return out
}

@ -16,10 +16,11 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
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.ConversionStatus": schema_pkg_apis_dashboard_v2alpha1_ConversionStatus(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.DashboardStatus": schema_pkg_apis_dashboard_v2alpha1_DashboardStatus(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),
@ -92,6 +93,36 @@ func schema_pkg_apis_dashboard_v2alpha1_AnnotationPermission(ref common.Referenc
}
}
func schema_pkg_apis_dashboard_v2alpha1_ConversionStatus(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{"object"},
Properties: map[string]spec.Schema{
"failed": {
SchemaProps: spec.SchemaProps{
Type: []string{"boolean"},
Format: "",
},
},
"storedVersion": {
SchemaProps: spec.SchemaProps{
Type: []string{"string"},
Format: "",
},
},
"error": {
SchemaProps: spec.SchemaProps{
Type: []string{"string"},
Format: "",
},
},
},
},
},
}
}
func schema_pkg_apis_dashboard_v2alpha1_Dashboard(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
@ -122,8 +153,13 @@ func schema_pkg_apis_dashboard_v2alpha1_Dashboard(ref common.ReferenceCallback)
"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"),
Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured"),
},
},
"status": {
SchemaProps: spec.SchemaProps{
Description: "Optional dashboard status",
Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardStatus"),
},
},
},
@ -131,7 +167,7 @@ func schema_pkg_apis_dashboard_v2alpha1_Dashboard(ref common.ReferenceCallback)
},
},
Dependencies: []string{
"github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
"github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
}
}
@ -252,38 +288,22 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardList(ref common.ReferenceCallba
}
}
func schema_pkg_apis_dashboard_v2alpha1_DashboardSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
func schema_pkg_apis_dashboard_v2alpha1_DashboardStatus(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": {
"conversion": {
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: "",
},
},
},
Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.ConversionStatus"),
},
},
},
Required: []string{"title", "Object"},
},
},
Dependencies: []string{
"github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.ConversionStatus"},
}
}
@ -415,8 +435,13 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardWithAccessInfo(ref common.Refer
"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"),
Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured"),
},
},
"status": {
SchemaProps: spec.SchemaProps{
Description: "Optional dashboard status",
Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardStatus"),
},
},
"access": {
@ -430,7 +455,7 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardWithAccessInfo(ref common.Refer
},
},
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"},
"github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardAccess", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
}
}

@ -1 +1,2 @@
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,LibraryPanelStatus,Warnings
API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardStatus,ConversionStatus

@ -1,360 +0,0 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
// SPDX-License-Identifier: AGPL-3.0-only
// Code generated by deepcopy-gen. DO NOT EDIT.
package 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 *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
}

@ -11,7 +11,7 @@ import (
"github.com/prometheus/client_golang/prometheus"
"k8s.io/apimachinery/pkg/runtime/schema"
dashboard "github.com/grafana/grafana/pkg/apis/dashboard"
dashboard "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1"
folders "github.com/grafana/grafana/pkg/apis/folder/v0alpha1"
authlib "github.com/grafana/authlib/types"

@ -1,18 +0,0 @@
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
}
func FromInternalDashboard(scheme *runtime.Scheme, dash *dashboard.Dashboard, obj runtime.Object) error {
return scheme.Convert(dash, obj, nil)
}

@ -1,104 +0,0 @@
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: dashboardinternal.DashboardSpec{Title: title, Unstructured: 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)
}

@ -1,19 +1,21 @@
package dashboard
import (
"encoding/json"
"fmt"
"k8s.io/apimachinery/pkg/runtime"
commonV0 "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
dashboard "github.com/grafana/grafana/pkg/apis/dashboard"
"github.com/grafana/grafana/pkg/apimachinery/utils"
dashboardV0 "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1"
dashboardV1 "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1"
dashboardV2 "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1"
"github.com/grafana/grafana/pkg/storage/unified/apistore"
)
func NewDashboardLargeObjectSupport(scheme *runtime.Scheme) *apistore.BasicLargeObjectSupport {
return &apistore.BasicLargeObjectSupport{
TheGroupResource: dashboard.DashboardResourceInfo.GroupResource(),
TheGroupResource: dashboardV0.DashboardResourceInfo.GroupResource(),
// byte size, while testing lets do almost everything (10bytes)
ThresholdSize: 10,
@ -22,45 +24,56 @@ func NewDashboardLargeObjectSupport(scheme *runtime.Scheme) *apistore.BasicLarge
MaxByteSize: 10 * 1024 * 1024,
ReduceSpec: func(obj runtime.Object) error {
dash, err := ToInternalDashboard(scheme, obj)
meta, err := utils.MetaAccessor(obj)
if err != nil {
return err
}
old := dash.Spec.Object
spec := commonV0.Unstructured{Object: make(map[string]any)}
dash.Spec = dashboard.DashboardSpec{Unstructured: spec}
dash.SetManagedFields(nil) // this could be bigger than the object!
keep := []string{"title", "description", "tags", "schemaVersion"}
for _, k := range keep {
v, ok := old[k]
if ok {
spec.Object[k] = v
}
}
if err := scheme.Convert(dash, obj, nil); err != nil {
return fmt.Errorf("failed to update original object: %w", err)
switch dash := obj.(type) {
case *dashboardV0.Dashboard:
reduceUnstructredSpec(&dash.Spec)
case *dashboardV1.Dashboard:
reduceUnstructredSpec(&dash.Spec)
case *dashboardV2.Dashboard:
reduceUnstructredSpec(&dash.Spec)
default:
return fmt.Errorf("unsupported dashboard type %T", obj)
}
meta.SetManagedFields(nil) // this could be bigger than the object!
return nil
},
RebuildSpec: func(obj runtime.Object, blob []byte) error {
dash, err := ToInternalDashboard(scheme, obj)
body := commonV0.Unstructured{}
err := body.UnmarshalJSON(blob)
if err != nil {
return err
}
if err := json.Unmarshal(blob, &dash.Spec); err != nil {
return fmt.Errorf("failed to unmarshal blob into spec: %w", err)
}
if err := scheme.Convert(dash, obj, nil); err != nil {
return fmt.Errorf("failed to update original object: %w", err)
switch dash := obj.(type) {
case *dashboardV0.Dashboard:
dash.Spec = body
case *dashboardV1.Dashboard:
dash.Spec = body
case *dashboardV2.Dashboard:
dash.Spec = body
default:
return fmt.Errorf("unsupported dashboard type %T", obj)
}
return nil
},
}
}
func reduceUnstructredSpec(spec *commonV0.Unstructured) {
vals := make(map[string]any, 5)
keep := []string{"title", "description", "tags", "schemaVersion"}
for _, k := range keep {
v, ok := spec.Object[k]
if ok {
vals[k] = v
}
}
spec.Object = vals
}

@ -5,12 +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"
"k8s.io/apimachinery/pkg/runtime"
dashboardv0alpha1 "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1"
)
func TestLargeDashboardSupport(t *testing.T) {
@ -41,9 +41,6 @@ func TestLargeDashboardSupport(t *testing.T) {
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
@ -53,7 +50,7 @@ func TestLargeDashboardSupport(t *testing.T) {
small, err := json.MarshalIndent(&dash.Spec, "", " ")
require.NoError(t, err)
require.JSONEq(t, `{
"schemaVersion": 41,
"schemaVersion": 33,
"title": "Panel tests - All panels",
"tags": ["gdev","panel-tests","all-panels"]
}`, string(small))

@ -12,7 +12,7 @@ import (
authlib "github.com/grafana/authlib/types"
"github.com/grafana/grafana/pkg/apimachinery/utils"
dashboard "github.com/grafana/grafana/pkg/apis/dashboard"
dashboard "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1"
folders "github.com/grafana/grafana/pkg/apis/folder/v0alpha1"
"github.com/grafana/grafana/pkg/infra/db"
"github.com/grafana/grafana/pkg/services/provisioning"

@ -9,10 +9,12 @@ SELECT
dashboard.created, created_user.uid as created_by, dashboard.created_by as created_by_id,
{{ if .Query.UseHistoryTable }}
dashboard_version.created, updated_user.uid as updated_by,updated_user.id as created_by_id,
dashboard_version.version, dashboard_version.message, dashboard_version.data
dashboard_version.version, dashboard_version.message,
dashboard_version.data, dashboard_version.api_version
{{ else }}
dashboard.updated, updated_user.uid as updated_by, dashboard.updated_by as updated_by_id,
dashboard.version, '' as message, dashboard.data
dashboard.version, '' as message,
dashboard.data, dashboard.api_version
{{ end }}
FROM {{ .Ident .DashboardTable }} as dashboard
{{ if .Query.UseHistoryTable }}
@ -44,7 +46,7 @@ WHERE dashboard.is_folder = {{ .Arg .Query.GetFolders }}
{{ end }}
{{ if .Query.GetTrash }}
AND dashboard.deleted IS NOT NULL
{{ else if .Query.LastID }}
{{ else }}
AND dashboard.deleted IS NULL
{{ end }}
ORDER BY dashboard.id DESC

@ -7,6 +7,7 @@ import (
"fmt"
"path/filepath"
"strconv"
"strings"
"sync"
"time"
@ -17,7 +18,8 @@ import (
"github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/apimachinery/utils"
dashboard "github.com/grafana/grafana/pkg/apis/dashboard"
dashboardOG "github.com/grafana/grafana/pkg/apis/dashboard"
dashboard "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/registry/apis/dashboard/legacysearcher"
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
@ -255,6 +257,7 @@ func (a *dashboardSqlAccess) scanRow(rows *sql.Rows, history bool) (*dashboardRo
var createdBy sql.NullString
var createdByID sql.NullInt64
var message sql.NullString
var apiVersion sql.NullString
var plugin_id sql.NullString
var origin_name sql.NullString
@ -269,8 +272,11 @@ func (a *dashboardSqlAccess) scanRow(rows *sql.Rows, history bool) (*dashboardRo
&origin_name, &origin_path, &origin_hash, &origin_ts,
&created, &createdBy, &createdByID,
&updated, &updatedBy, &updatedByID,
&version, &message, &data,
&version, &message, &data, &apiVersion,
)
if apiVersion.String == "" {
apiVersion.String = "v0alpha1" // default value
}
row.token = &continueToken{orgId: orgId, id: dashboard_id}
// when listing from the history table, we want to use the version as the ID to continue from
@ -281,6 +287,7 @@ func (a *dashboardSqlAccess) scanRow(rows *sql.Rows, history bool) (*dashboardRo
row.RV = version
dash.ResourceVersion = fmt.Sprintf("%d", row.RV)
dash.Namespace = a.namespacer(orgId)
dash.APIVersion = fmt.Sprintf("%s/%s", dashboard.GROUP, apiVersion.String)
dash.UID = gapiutil.CalculateClusterWideUID(dash)
dash.SetCreationTimestamp(metav1.NewTime(created))
meta, err := utils.MetaAccessor(dash)
@ -313,7 +320,7 @@ func (a *dashboardSqlAccess) scanRow(rows *sql.Rows, history bool) (*dashboardRo
ts := time.Unix(origin_ts.Int64, 0)
repo := &utils.ResourceRepositoryInfo{
Name: dashboard.ProvisionedFileNameWithPrefix(origin_name.String),
Name: dashboardOG.ProvisionedFileNameWithPrefix(origin_name.String),
Hash: origin_hash.String,
Timestamp: &ts,
}
@ -332,7 +339,7 @@ func (a *dashboardSqlAccess) scanRow(rows *sql.Rows, history bool) (*dashboardRo
meta.SetRepositoryInfo(repo)
} else if plugin_id.String != "" {
meta.SetRepositoryInfo(&utils.ResourceRepositoryInfo{
Name: dashboard.PluginIDRepoName,
Name: dashboardOG.PluginIDRepoName,
Path: plugin_id.String,
})
}
@ -421,18 +428,20 @@ func (a *dashboardSqlAccess) SaveDashboard(ctx context.Context, orgId int64, das
}
}
apiVersion := strings.TrimPrefix(dash.APIVersion, dashboard.GROUP+"/")
meta, err := utils.MetaAccessor(dash)
if err != nil {
return nil, false, err
}
out, err := a.dashStore.SaveDashboard(ctx, dashboards.SaveDashboardCommand{
OrgID: orgId,
Message: meta.GetMessage(),
PluginID: dashboard.GetPluginIDFromMeta(meta),
Dashboard: simplejson.NewFromAny(dash.Spec.UnstructuredContent()),
FolderUID: meta.GetFolder(),
Overwrite: true, // already passed the revisionVersion checks!
UserID: userID,
OrgID: orgId,
Message: meta.GetMessage(),
PluginID: dashboardOG.GetPluginIDFromMeta(meta),
Dashboard: simplejson.NewFromAny(dash.Spec.UnstructuredContent()),
FolderUID: meta.GetFolder(),
Overwrite: true, // already passed the revisionVersion checks!
UserID: userID,
APIVersion: apiVersion,
})
if err != nil {
return nil, false, err

@ -11,7 +11,6 @@ import (
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
"github.com/grafana/grafana/pkg/apimachinery/utils"
dashboardinternal "github.com/grafana/grafana/pkg/apis/dashboard"
"github.com/grafana/grafana/pkg/services/provisioning"
)
@ -28,7 +27,7 @@ func TestScanRow(t *testing.T) {
provisioning: provisioner,
}
columns := []string{"orgId", "dashboard_id", "name", "folder_uid", "deleted", "plugin_id", "origin_name", "origin_path", "origin_hash", "origin_ts", "created", "createdBy", "createdByID", "updated", "updatedBy", "updatedByID", "version", "message", "data"}
columns := []string{"orgId", "dashboard_id", "name", "folder_uid", "deleted", "plugin_id", "origin_name", "origin_path", "origin_hash", "origin_ts", "created", "createdBy", "createdByID", "updated", "updatedBy", "updatedByID", "version", "message", "data", "api_version"}
id := int64(100)
title := "Test Dashboard"
folderUID := "folder123"
@ -40,7 +39,7 @@ func TestScanRow(t *testing.T) {
updatedUser := "updator"
t.Run("Should scan a valid row correctly", func(t *testing.T) {
rows := sqlmock.NewRows(columns).AddRow(1, id, title, folderUID, nil, "", "", "", "", 0, timestamp, createdUser, 0, timestamp, updatedUser, 0, version, message, []byte(`{"key": "value"}`))
rows := sqlmock.NewRows(columns).AddRow(1, id, title, folderUID, nil, "", "", "", "", 0, timestamp, createdUser, 0, timestamp, updatedUser, 0, version, message, []byte(`{"key": "value"}`), "vXyz")
mock.ExpectQuery("SELECT *").WillReturnRows(rows)
resultRows, err := mockDB.Query("SELECT *")
require.NoError(t, err)
@ -52,10 +51,8 @@ func TestScanRow(t *testing.T) {
require.NotNil(t, row)
require.Equal(t, "Test Dashboard", row.Dash.Name)
require.Equal(t, version, row.RV) // rv should be the dashboard version
require.Equal(t, dashboardinternal.DashboardSpec{
Unstructured: common.Unstructured{
Object: map[string]interface{}{"key": "value"},
},
require.Equal(t, common.Unstructured{
Object: map[string]interface{}{"key": "value"},
}, row.Dash.Spec)
require.Equal(t, "default", row.Dash.Namespace)
require.Equal(t, &continueToken{orgId: int64(1), id: id}, row.token)
@ -69,10 +66,11 @@ func TestScanRow(t *testing.T) {
require.Equal(t, "user:"+updatedUser, meta.GetUpdatedBy()) // should be prefixed by user:
require.Equal(t, message, meta.GetMessage())
require.Equal(t, folderUID, meta.GetFolder())
require.Equal(t, "dashboard.grafana.app/vXyz", row.Dash.APIVersion)
})
t.Run("File provisioned dashboard should have annotations", func(t *testing.T) {
rows := sqlmock.NewRows(columns).AddRow(1, id, title, folderUID, nil, "", "provisioner", pathToFile, "hashing", 100000, timestamp, createdUser, 0, timestamp, updatedUser, 0, version, message, []byte(`{"key": "value"}`))
rows := sqlmock.NewRows(columns).AddRow(1, id, title, folderUID, nil, "", "provisioner", pathToFile, "hashing", 100000, timestamp, createdUser, 0, timestamp, updatedUser, 0, version, message, []byte(`{"key": "value"}`), "vXyz")
mock.ExpectQuery("SELECT *").WillReturnRows(rows)
resultRows, err := mockDB.Query("SELECT *")
require.NoError(t, err)
@ -94,7 +92,7 @@ func TestScanRow(t *testing.T) {
})
t.Run("Plugin provisioned dashboard should have annotations", func(t *testing.T) {
rows := sqlmock.NewRows(columns).AddRow(1, id, title, folderUID, nil, "slo", "", "", "", 0, timestamp, createdUser, 0, timestamp, updatedUser, 0, version, message, []byte(`{"key": "value"}`))
rows := sqlmock.NewRows(columns).AddRow(1, id, title, folderUID, nil, "slo", "", "", "", 0, timestamp, createdUser, 0, timestamp, updatedUser, 0, version, message, []byte(`{"key": "value"}`), "vXyz")
mock.ExpectQuery("SELECT *").WillReturnRows(rows)
resultRows, err := mockDB.Query("SELECT *")
require.NoError(t, err)

@ -10,7 +10,7 @@ import (
claims "github.com/grafana/authlib/types"
"github.com/grafana/grafana/pkg/apimachinery/utils"
dashboard "github.com/grafana/grafana/pkg/apis/dashboard"
dashboard "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1"
"github.com/grafana/grafana/pkg/storage/unified/resource"
)

@ -8,11 +8,13 @@ SELECT
provisioning.updated as repo_ts,
dashboard.created, created_user.uid as created_by, dashboard.created_by as created_by_id,
dashboard.updated, updated_user.uid as updated_by, dashboard.updated_by as updated_by_id,
dashboard.version, '' as message, dashboard.data
dashboard.version, '' as message,
dashboard.data, dashboard.api_version
FROM `grafana`.`dashboard` as dashboard
LEFT OUTER JOIN `grafana`.`dashboard_provisioning` as provisioning ON dashboard.id = provisioning.dashboard_id
LEFT OUTER JOIN `grafana`.`user` as created_user ON dashboard.created_by = created_user.id
LEFT OUTER JOIN `grafana`.`user` as updated_user ON dashboard.updated_by = updated_user.id
WHERE dashboard.is_folder = FALSE
AND dashboard.org_id = 2
AND dashboard.deleted IS NULL
ORDER BY dashboard.id DESC

@ -8,7 +8,8 @@ SELECT
provisioning.updated as repo_ts,
dashboard.created, created_user.uid as created_by, dashboard.created_by as created_by_id,
dashboard.updated, updated_user.uid as updated_by, dashboard.updated_by as updated_by_id,
dashboard.version, '' as message, dashboard.data
dashboard.version, '' as message,
dashboard.data, dashboard.api_version
FROM `grafana`.`dashboard` as dashboard
LEFT OUTER JOIN `grafana`.`dashboard_provisioning` as provisioning ON dashboard.id = provisioning.dashboard_id
LEFT OUTER JOIN `grafana`.`user` as created_user ON dashboard.created_by = created_user.id

@ -8,7 +8,8 @@ SELECT
provisioning.updated as repo_ts,
dashboard.created, created_user.uid as created_by, dashboard.created_by as created_by_id,
dashboard_version.created, updated_user.uid as updated_by,updated_user.id as created_by_id,
dashboard_version.version, dashboard_version.message, dashboard_version.data
dashboard_version.version, dashboard_version.message,
dashboard_version.data, dashboard_version.api_version
FROM `grafana`.`dashboard` as dashboard
LEFT OUTER JOIN `grafana`.`dashboard_version` as dashboard_version ON dashboard.id = dashboard_version.dashboard_id
LEFT OUTER JOIN `grafana`.`dashboard_provisioning` as provisioning ON dashboard.id = provisioning.dashboard_id

@ -8,11 +8,13 @@ SELECT
provisioning.updated as repo_ts,
dashboard.created, created_user.uid as created_by, dashboard.created_by as created_by_id,
dashboard.updated, updated_user.uid as updated_by, dashboard.updated_by as updated_by_id,
dashboard.version, '' as message, dashboard.data
dashboard.version, '' as message,
dashboard.data, dashboard.api_version
FROM `grafana`.`dashboard` as dashboard
LEFT OUTER JOIN `grafana`.`dashboard_provisioning` as provisioning ON dashboard.id = provisioning.dashboard_id
LEFT OUTER JOIN `grafana`.`user` as created_user ON dashboard.created_by = created_user.id
LEFT OUTER JOIN `grafana`.`user` as updated_user ON dashboard.updated_by = updated_user.id
WHERE dashboard.is_folder = TRUE
AND dashboard.org_id = 2
AND dashboard.deleted IS NULL
ORDER BY dashboard.id DESC

@ -8,7 +8,8 @@ SELECT
provisioning.updated as repo_ts,
dashboard.created, created_user.uid as created_by, dashboard.created_by as created_by_id,
dashboard.updated, updated_user.uid as updated_by, dashboard.updated_by as updated_by_id,
dashboard.version, '' as message, dashboard.data
dashboard.version, '' as message,
dashboard.data, dashboard.api_version
FROM `grafana`.`dashboard` as dashboard
LEFT OUTER JOIN `grafana`.`dashboard_provisioning` as provisioning ON dashboard.id = provisioning.dashboard_id
LEFT OUTER JOIN `grafana`.`user` as created_user ON dashboard.created_by = created_user.id
@ -16,4 +17,5 @@ LEFT OUTER JOIN `grafana`.`user` as updated_user ON dashboard.updated_by = updat
WHERE dashboard.is_folder = FALSE
AND dashboard.org_id = 2
AND dashboard.uid = 'UUU'
AND dashboard.deleted IS NULL
ORDER BY dashboard.id DESC

@ -8,7 +8,8 @@ SELECT
provisioning.updated as repo_ts,
dashboard.created, created_user.uid as created_by, dashboard.created_by as created_by_id,
dashboard_version.created, updated_user.uid as updated_by,updated_user.id as created_by_id,
dashboard_version.version, dashboard_version.message, dashboard_version.data
dashboard_version.version, dashboard_version.message,
dashboard_version.data, dashboard_version.api_version
FROM `grafana`.`dashboard` as dashboard
LEFT OUTER JOIN `grafana`.`dashboard_version` as dashboard_version ON dashboard.id = dashboard_version.dashboard_id
LEFT OUTER JOIN `grafana`.`dashboard_provisioning` as provisioning ON dashboard.id = provisioning.dashboard_id

@ -8,7 +8,8 @@ SELECT
provisioning.updated as repo_ts,
dashboard.created, created_user.uid as created_by, dashboard.created_by as created_by_id,
dashboard.updated, updated_user.uid as updated_by, dashboard.updated_by as updated_by_id,
dashboard.version, '' as message, dashboard.data
dashboard.version, '' as message,
dashboard.data, dashboard.api_version
FROM `grafana`.`dashboard` as dashboard
LEFT OUTER JOIN `grafana`.`dashboard_provisioning` as provisioning ON dashboard.id = provisioning.dashboard_id
LEFT OUTER JOIN `grafana`.`user` as created_user ON dashboard.created_by = created_user.id

@ -8,11 +8,13 @@ SELECT
provisioning.updated as repo_ts,
dashboard.created, created_user.uid as created_by, dashboard.created_by as created_by_id,
dashboard.updated, updated_user.uid as updated_by, dashboard.updated_by as updated_by_id,
dashboard.version, '' as message, dashboard.data
dashboard.version, '' as message,
dashboard.data, dashboard.api_version
FROM "grafana"."dashboard" as dashboard
LEFT OUTER JOIN "grafana"."dashboard_provisioning" as provisioning ON dashboard.id = provisioning.dashboard_id
LEFT OUTER JOIN "grafana"."user" as created_user ON dashboard.created_by = created_user.id
LEFT OUTER JOIN "grafana"."user" as updated_user ON dashboard.updated_by = updated_user.id
WHERE dashboard.is_folder = FALSE
AND dashboard.org_id = 2
AND dashboard.deleted IS NULL
ORDER BY dashboard.id DESC

@ -8,7 +8,8 @@ SELECT
provisioning.updated as repo_ts,
dashboard.created, created_user.uid as created_by, dashboard.created_by as created_by_id,
dashboard.updated, updated_user.uid as updated_by, dashboard.updated_by as updated_by_id,
dashboard.version, '' as message, dashboard.data
dashboard.version, '' as message,
dashboard.data, dashboard.api_version
FROM "grafana"."dashboard" as dashboard
LEFT OUTER JOIN "grafana"."dashboard_provisioning" as provisioning ON dashboard.id = provisioning.dashboard_id
LEFT OUTER JOIN "grafana"."user" as created_user ON dashboard.created_by = created_user.id

@ -8,7 +8,8 @@ SELECT
provisioning.updated as repo_ts,
dashboard.created, created_user.uid as created_by, dashboard.created_by as created_by_id,
dashboard_version.created, updated_user.uid as updated_by,updated_user.id as created_by_id,
dashboard_version.version, dashboard_version.message, dashboard_version.data
dashboard_version.version, dashboard_version.message,
dashboard_version.data, dashboard_version.api_version
FROM "grafana"."dashboard" as dashboard
LEFT OUTER JOIN "grafana"."dashboard_version" as dashboard_version ON dashboard.id = dashboard_version.dashboard_id
LEFT OUTER JOIN "grafana"."dashboard_provisioning" as provisioning ON dashboard.id = provisioning.dashboard_id

@ -8,11 +8,13 @@ SELECT
provisioning.updated as repo_ts,
dashboard.created, created_user.uid as created_by, dashboard.created_by as created_by_id,
dashboard.updated, updated_user.uid as updated_by, dashboard.updated_by as updated_by_id,
dashboard.version, '' as message, dashboard.data
dashboard.version, '' as message,
dashboard.data, dashboard.api_version
FROM "grafana"."dashboard" as dashboard
LEFT OUTER JOIN "grafana"."dashboard_provisioning" as provisioning ON dashboard.id = provisioning.dashboard_id
LEFT OUTER JOIN "grafana"."user" as created_user ON dashboard.created_by = created_user.id
LEFT OUTER JOIN "grafana"."user" as updated_user ON dashboard.updated_by = updated_user.id
WHERE dashboard.is_folder = TRUE
AND dashboard.org_id = 2
AND dashboard.deleted IS NULL
ORDER BY dashboard.id DESC

@ -8,7 +8,8 @@ SELECT
provisioning.updated as repo_ts,
dashboard.created, created_user.uid as created_by, dashboard.created_by as created_by_id,
dashboard.updated, updated_user.uid as updated_by, dashboard.updated_by as updated_by_id,
dashboard.version, '' as message, dashboard.data
dashboard.version, '' as message,
dashboard.data, dashboard.api_version
FROM "grafana"."dashboard" as dashboard
LEFT OUTER JOIN "grafana"."dashboard_provisioning" as provisioning ON dashboard.id = provisioning.dashboard_id
LEFT OUTER JOIN "grafana"."user" as created_user ON dashboard.created_by = created_user.id
@ -16,4 +17,5 @@ LEFT OUTER JOIN "grafana"."user" as updated_user ON dashboard.updated_by = updat
WHERE dashboard.is_folder = FALSE
AND dashboard.org_id = 2
AND dashboard.uid = 'UUU'
AND dashboard.deleted IS NULL
ORDER BY dashboard.id DESC

@ -8,7 +8,8 @@ SELECT
provisioning.updated as repo_ts,
dashboard.created, created_user.uid as created_by, dashboard.created_by as created_by_id,
dashboard_version.created, updated_user.uid as updated_by,updated_user.id as created_by_id,
dashboard_version.version, dashboard_version.message, dashboard_version.data
dashboard_version.version, dashboard_version.message,
dashboard_version.data, dashboard_version.api_version
FROM "grafana"."dashboard" as dashboard
LEFT OUTER JOIN "grafana"."dashboard_version" as dashboard_version ON dashboard.id = dashboard_version.dashboard_id
LEFT OUTER JOIN "grafana"."dashboard_provisioning" as provisioning ON dashboard.id = provisioning.dashboard_id

@ -8,7 +8,8 @@ SELECT
provisioning.updated as repo_ts,
dashboard.created, created_user.uid as created_by, dashboard.created_by as created_by_id,
dashboard.updated, updated_user.uid as updated_by, dashboard.updated_by as updated_by_id,
dashboard.version, '' as message, dashboard.data
dashboard.version, '' as message,
dashboard.data, dashboard.api_version
FROM "grafana"."dashboard" as dashboard
LEFT OUTER JOIN "grafana"."dashboard_provisioning" as provisioning ON dashboard.id = provisioning.dashboard_id
LEFT OUTER JOIN "grafana"."user" as created_user ON dashboard.created_by = created_user.id

@ -8,11 +8,13 @@ SELECT
provisioning.updated as repo_ts,
dashboard.created, created_user.uid as created_by, dashboard.created_by as created_by_id,
dashboard.updated, updated_user.uid as updated_by, dashboard.updated_by as updated_by_id,
dashboard.version, '' as message, dashboard.data
dashboard.version, '' as message,
dashboard.data, dashboard.api_version
FROM "grafana"."dashboard" as dashboard
LEFT OUTER JOIN "grafana"."dashboard_provisioning" as provisioning ON dashboard.id = provisioning.dashboard_id
LEFT OUTER JOIN "grafana"."user" as created_user ON dashboard.created_by = created_user.id
LEFT OUTER JOIN "grafana"."user" as updated_user ON dashboard.updated_by = updated_user.id
WHERE dashboard.is_folder = FALSE
AND dashboard.org_id = 2
AND dashboard.deleted IS NULL
ORDER BY dashboard.id DESC

@ -8,7 +8,8 @@ SELECT
provisioning.updated as repo_ts,
dashboard.created, created_user.uid as created_by, dashboard.created_by as created_by_id,
dashboard.updated, updated_user.uid as updated_by, dashboard.updated_by as updated_by_id,
dashboard.version, '' as message, dashboard.data
dashboard.version, '' as message,
dashboard.data, dashboard.api_version
FROM "grafana"."dashboard" as dashboard
LEFT OUTER JOIN "grafana"."dashboard_provisioning" as provisioning ON dashboard.id = provisioning.dashboard_id
LEFT OUTER JOIN "grafana"."user" as created_user ON dashboard.created_by = created_user.id

@ -8,7 +8,8 @@ SELECT
provisioning.updated as repo_ts,
dashboard.created, created_user.uid as created_by, dashboard.created_by as created_by_id,
dashboard_version.created, updated_user.uid as updated_by,updated_user.id as created_by_id,
dashboard_version.version, dashboard_version.message, dashboard_version.data
dashboard_version.version, dashboard_version.message,
dashboard_version.data, dashboard_version.api_version
FROM "grafana"."dashboard" as dashboard
LEFT OUTER JOIN "grafana"."dashboard_version" as dashboard_version ON dashboard.id = dashboard_version.dashboard_id
LEFT OUTER JOIN "grafana"."dashboard_provisioning" as provisioning ON dashboard.id = provisioning.dashboard_id

@ -8,11 +8,13 @@ SELECT
provisioning.updated as repo_ts,
dashboard.created, created_user.uid as created_by, dashboard.created_by as created_by_id,
dashboard.updated, updated_user.uid as updated_by, dashboard.updated_by as updated_by_id,
dashboard.version, '' as message, dashboard.data
dashboard.version, '' as message,
dashboard.data, dashboard.api_version
FROM "grafana"."dashboard" as dashboard
LEFT OUTER JOIN "grafana"."dashboard_provisioning" as provisioning ON dashboard.id = provisioning.dashboard_id
LEFT OUTER JOIN "grafana"."user" as created_user ON dashboard.created_by = created_user.id
LEFT OUTER JOIN "grafana"."user" as updated_user ON dashboard.updated_by = updated_user.id
WHERE dashboard.is_folder = TRUE
AND dashboard.org_id = 2
AND dashboard.deleted IS NULL
ORDER BY dashboard.id DESC

@ -8,7 +8,8 @@ SELECT
provisioning.updated as repo_ts,
dashboard.created, created_user.uid as created_by, dashboard.created_by as created_by_id,
dashboard.updated, updated_user.uid as updated_by, dashboard.updated_by as updated_by_id,
dashboard.version, '' as message, dashboard.data
dashboard.version, '' as message,
dashboard.data, dashboard.api_version
FROM "grafana"."dashboard" as dashboard
LEFT OUTER JOIN "grafana"."dashboard_provisioning" as provisioning ON dashboard.id = provisioning.dashboard_id
LEFT OUTER JOIN "grafana"."user" as created_user ON dashboard.created_by = created_user.id
@ -16,4 +17,5 @@ LEFT OUTER JOIN "grafana"."user" as updated_user ON dashboard.updated_by = updat
WHERE dashboard.is_folder = FALSE
AND dashboard.org_id = 2
AND dashboard.uid = 'UUU'
AND dashboard.deleted IS NULL
ORDER BY dashboard.id DESC

@ -8,7 +8,8 @@ SELECT
provisioning.updated as repo_ts,
dashboard.created, created_user.uid as created_by, dashboard.created_by as created_by_id,
dashboard_version.created, updated_user.uid as updated_by,updated_user.id as created_by_id,
dashboard_version.version, dashboard_version.message, dashboard_version.data
dashboard_version.version, dashboard_version.message,
dashboard_version.data, dashboard_version.api_version
FROM "grafana"."dashboard" as dashboard
LEFT OUTER JOIN "grafana"."dashboard_version" as dashboard_version ON dashboard.id = dashboard_version.dashboard_id
LEFT OUTER JOIN "grafana"."dashboard_provisioning" as provisioning ON dashboard.id = provisioning.dashboard_id

@ -8,7 +8,8 @@ SELECT
provisioning.updated as repo_ts,
dashboard.created, created_user.uid as created_by, dashboard.created_by as created_by_id,
dashboard.updated, updated_user.uid as updated_by, dashboard.updated_by as updated_by_id,
dashboard.version, '' as message, dashboard.data
dashboard.version, '' as message,
dashboard.data, dashboard.api_version
FROM "grafana"."dashboard" as dashboard
LEFT OUTER JOIN "grafana"."dashboard_provisioning" as provisioning ON dashboard.id = provisioning.dashboard_id
LEFT OUTER JOIN "grafana"."user" as created_user ON dashboard.created_by = created_user.id

@ -3,7 +3,7 @@ package legacy
import (
"context"
dashboard "github.com/grafana/grafana/pkg/apis/dashboard"
dashboard "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1"
"github.com/grafana/grafana/pkg/storage/unified/resource"
)

@ -14,21 +14,15 @@ import (
grafanaregistry "github.com/grafana/grafana/pkg/apiserver/registry/generic"
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
"github.com/grafana/grafana/pkg/registry/apis/dashboard/legacy"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/storage/unified/apistore"
"github.com/grafana/grafana/pkg/storage/unified/resource"
)
type DashboardStorage struct {
Resource utils.ResourceInfo
Access legacy.DashboardAccess
TableConverter rest.TableConvertor
Server resource.ResourceServer
Features featuremgmt.FeatureToggles
Access legacy.DashboardAccess
}
func (s *DashboardStorage) NewStore(scheme *runtime.Scheme, defaultOptsGetter generic.RESTOptionsGetter, reg prometheus.Registerer) (grafanarest.Storage, error) {
func (s *DashboardStorage) NewStore(dash utils.ResourceInfo, scheme *runtime.Scheme, defaultOptsGetter generic.RESTOptionsGetter, reg prometheus.Registerer) (grafanarest.Storage, error) {
server, err := resource.NewResourceServer(resource.ResourceServerOptions{
Backend: s.Access,
Reg: reg,
@ -36,10 +30,8 @@ func (s *DashboardStorage) NewStore(scheme *runtime.Scheme, defaultOptsGetter ge
if err != nil {
return nil, err
}
s.Server = server
resourceInfo := s.Resource
defaultOpts, err := defaultOptsGetter.GetRESTOptions(resourceInfo.GroupResource(), nil)
defaultOpts, err := defaultOptsGetter.GetRESTOptions(dash.GroupResource(), nil)
if err != nil {
return nil, err
}
@ -48,7 +40,7 @@ func (s *DashboardStorage) NewStore(scheme *runtime.Scheme, defaultOptsGetter ge
defaultOpts.StorageConfig.Config,
)
store, err := grafanaregistry.NewRegistryStore(scheme, resourceInfo, optsGetter)
store, err := grafanaregistry.NewRegistryStore(scheme, dash, optsGetter)
return &storeWrapper{
Store: store,
}, err

@ -7,10 +7,14 @@ import (
"strconv"
"strings"
"google.golang.org/grpc"
"k8s.io/apimachinery/pkg/selection"
claims "github.com/grafana/authlib/types"
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/apimachinery/utils"
"github.com/grafana/grafana/pkg/apis/dashboard"
dashboardOG "github.com/grafana/grafana/pkg/apis/dashboard"
dashboard "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1"
folderv0alpha1 "github.com/grafana/grafana/pkg/apis/folder/v0alpha1"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/dashboards/dashboardaccess"
@ -18,8 +22,6 @@ import (
"github.com/grafana/grafana/pkg/services/sqlstore/searchstore"
"github.com/grafana/grafana/pkg/storage/unified/resource"
unisearch "github.com/grafana/grafana/pkg/storage/unified/search"
"google.golang.org/grpc"
"k8s.io/apimachinery/pkg/selection"
)
type DashboardSearchClient struct {
@ -188,7 +190,7 @@ func (c *DashboardSearchClient) Search(ctx context.Context, req *resource.Resour
case resource.SEARCH_FIELD_REPOSITORY_NAME:
if field.Operator == string(selection.NotIn) {
for _, val := range vals {
name, _ := dashboard.GetProvisionedFileNameFromMeta(val)
name, _ := dashboardOG.GetProvisionedFileNameFromMeta(val)
query.ProvisionedReposNotIn = append(query.ProvisionedReposNotIn, name)
}
continue
@ -199,7 +201,7 @@ func (c *DashboardSearchClient) Search(ctx context.Context, req *resource.Resour
return nil, fmt.Errorf("only one repo name is supported")
}
query.ProvisionedRepo, _ = dashboard.GetProvisionedFileNameFromMeta(vals[0])
query.ProvisionedRepo, _ = dashboardOG.GetProvisionedFileNameFromMeta(vals[0])
}
}
searchFields := resource.StandardSearchFields()
@ -221,7 +223,7 @@ func (c *DashboardSearchClient) Search(ctx context.Context, req *resource.Resour
// legacy sql query, since legacy search does not support this
if query.ProvisionedRepo != "" || len(query.ProvisionedReposNotIn) > 0 {
var dashes []*dashboards.Dashboard
if query.ProvisionedRepo == dashboard.PluginIDRepoName {
if query.ProvisionedRepo == dashboardOG.PluginIDRepoName {
dashes, err = c.dashboardStore.GetDashboardsByPluginID(ctx, &dashboards.GetDashboardsByPluginIDQuery{
PluginID: query.ProvisionedPath,
OrgID: user.GetOrgID(),

@ -6,18 +6,19 @@ import (
"strconv"
"testing"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/selection"
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/apimachinery/utils"
"github.com/grafana/grafana/pkg/apis/dashboard"
dashboard "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/search/model"
"github.com/grafana/grafana/pkg/services/search/sort"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/storage/unified/resource"
unisearch "github.com/grafana/grafana/pkg/storage/unified/search"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/selection"
)
func TestDashboardSearchClient_Search(t *testing.T) {

@ -0,0 +1,54 @@
package dashboard
import (
"context"
"fmt"
"k8s.io/apiserver/pkg/admission"
"github.com/grafana/grafana/pkg/apimachinery/utils"
dashboardV0 "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1"
dashboardV1 "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1"
dashboardV2 "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1"
)
func (b *DashboardsAPIBuilder) Mutate(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) (err error) {
op := a.GetOperation()
// Mutate removes any internal ID set in the spec & adds it as a label
if op != admission.Create && op != admission.Update {
return nil
}
var internalID int64
obj := a.GetObject()
meta, err := utils.MetaAccessor(obj)
if err != nil {
return err
}
switch v := obj.(type) {
case *dashboardV0.Dashboard:
if id, ok := v.Spec.Object["id"].(float64); ok {
delete(v.Spec.Object, "id")
internalID = int64(id)
}
case *dashboardV1.Dashboard:
if id, ok := v.Spec.Object["id"].(float64); ok {
delete(v.Spec.Object, "id")
internalID = int64(id)
}
case *dashboardV2.Dashboard:
if id, ok := v.Spec.Object["id"].(float64); ok {
delete(v.Spec.Object, "id")
internalID = int64(id)
}
default:
return fmt.Errorf("mutation error: expected to dashboard, got %T", obj)
}
if internalID != 0 {
meta.SetDeprecatedInternalID(internalID) // nolint:staticcheck
}
return nil
}

@ -7,6 +7,8 @@ import (
"maps"
"path"
"github.com/prometheus/client_golang/prometheus"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
@ -17,16 +19,14 @@ import (
"k8s.io/kube-openapi/pkg/spec3"
"k8s.io/kube-openapi/pkg/validation/spec"
"github.com/prometheus/client_golang/prometheus"
claims "github.com/grafana/authlib/types"
"github.com/grafana/grafana/pkg/apimachinery/utils"
dashboardinternal "github.com/grafana/grafana/pkg/apis/dashboard"
"github.com/grafana/grafana/pkg/apis/dashboard"
"github.com/grafana/grafana/pkg/apis/dashboard/migration/conversion"
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"
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"
@ -100,10 +100,7 @@ func RegisterAPIService(
search: NewSearchHandler(tracing, dual, legacyDashboardSearcher, unified, features),
legacy: &DashboardStorage{
Resource: dashboardinternal.DashboardResourceInfo,
Access: legacy.NewDashboardAccess(dbp, namespacer, dashStore, provisioning, softDelete, sorter),
TableConverter: dashboardinternal.DashboardResourceInfo.TableConverter(),
Features: features,
Access: legacy.NewDashboardAccess(dbp, namespacer, dashStore, provisioning, softDelete, sorter),
},
reg: reg,
}
@ -121,9 +118,6 @@ func (b *DashboardsAPIBuilder) GetGroupVersions() []schema.GroupVersion {
func (b *DashboardsAPIBuilder) InstallSchema(scheme *runtime.Scheme) error {
b.scheme = scheme
if err := dashboardinternal.AddToScheme(scheme); err != nil {
return err
}
if err := dashboardv0alpha1.AddToScheme(scheme); err != nil {
return err
}
@ -133,6 +127,12 @@ func (b *DashboardsAPIBuilder) InstallSchema(scheme *runtime.Scheme) error {
if err := dashboardv2alpha1.AddToScheme(scheme); err != nil {
return err
}
// Register the explicit conversions
if err := conversion.RegisterConversions(scheme); err != nil {
return err
}
return scheme.SetVersionPriority(b.GetGroupVersions()...)
}
@ -154,11 +154,13 @@ func (b *DashboardsAPIBuilder) Validate(ctx context.Context, a admission.Attribu
provisioningData, err := b.dashboardProvisioningService.GetProvisionedDashboardDataByDashboardUID(ctx, nsInfo.OrgID, a.GetName())
if err != nil {
if errors.Is(err, dashboards.ErrProvisionedDashboardNotFound) {
if errors.Is(err, dashboards.ErrProvisionedDashboardNotFound) ||
errors.Is(err, dashboards.ErrDashboardNotFound) ||
apierrors.IsNotFound(err) {
return nil
}
return fmt.Errorf("%v: %w", "failed to check if dashboard is provisioned", err)
return fmt.Errorf("%v: %w", "delete hook failed to check if dashboard is provisioned", err)
}
if provisioningData != nil {
@ -170,144 +172,130 @@ func (b *DashboardsAPIBuilder) Validate(ctx context.Context, a admission.Attribu
return nil
}
// Mutate removes any internal ID set in the spec & adds it as a label
func (b *DashboardsAPIBuilder) Mutate(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) (err error) {
op := a.GetOperation()
if op != admission.Create && op != admission.Update {
return nil
}
obj := a.GetObject()
dash, ok := obj.(*dashboardinternal.Dashboard)
if !ok {
return fmt.Errorf("mutation error: expected *dashboardinternal.Dashboard, got %T", obj)
}
if id, ok := dash.Spec.Object["id"].(float64); ok {
delete(dash.Spec.Object, "id")
if id != 0 {
meta, err := utils.MetaAccessor(obj)
if err != nil {
return err
}
meta.SetDeprecatedInternalID(int64(id)) // nolint:staticcheck
}
}
return nil
}
func (b *DashboardsAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.APIGroupInfo, opts builder.APIGroupOptions) error {
internalDashResourceInfo := dashboardinternal.DashboardResourceInfo
legacyStore, err := b.legacy.NewStore(opts.Scheme, opts.OptsGetter, b.reg)
if err != nil {
return err
}
storageOpts := apistore.StorageOptions{
RequireDeprecatedInternalID: true,
}
// Split dashboards when they are large
var largeObjects apistore.LargeObjectSupport
if b.legacy.Features.IsEnabledGlobally(featuremgmt.FlagUnifiedStorageBigObjectsSupport) {
if b.features.IsEnabledGlobally(featuremgmt.FlagUnifiedStorageBigObjectsSupport) {
largeObjects = NewDashboardLargeObjectSupport(opts.Scheme)
storageOpts.LargeObjectSupport = largeObjects
}
opts.StorageOptions(internalDashResourceInfo.GroupResource(), storageOpts)
opts.StorageOptions(dashboardv0alpha1.DashboardResourceInfo.GroupResource(), storageOpts)
// v0alpha1
storage, err := b.storageForVersion(opts, legacyStore, largeObjects, func() runtime.Object {
return &dashboardv0alpha1.DashboardWithAccessInfo{}
})
if err != nil {
if err := b.storageForVersion(apiGroupInfo, opts, largeObjects,
dashboardv0alpha1.DashboardResourceInfo,
dashboardv0alpha1.LibraryPanelResourceInfo,
func(obj runtime.Object, access *dashboard.DashboardAccess) (v runtime.Object, err error) {
dto := &dashboardv0alpha1.DashboardWithAccessInfo{}
dash, ok := obj.(*dashboardv0alpha1.Dashboard)
if ok {
dto.Dashboard = *dash
}
if access != nil {
err = b.scheme.Convert(access, &dto.Access, nil)
}
return dto, err
}); err != nil {
return err
}
apiGroupInfo.VersionedResourcesStorageMap[dashboardv0alpha1.VERSION] = storage
// v1alpha1
storage, err = b.storageForVersion(opts, legacyStore, largeObjects, func() runtime.Object {
return &dashboardv1alpha1.DashboardWithAccessInfo{}
})
if err != nil {
if err := b.storageForVersion(apiGroupInfo, opts, largeObjects,
dashboardv1alpha1.DashboardResourceInfo,
dashboardv1alpha1.LibraryPanelResourceInfo,
func(obj runtime.Object, access *dashboard.DashboardAccess) (v runtime.Object, err error) {
dto := &dashboardv1alpha1.DashboardWithAccessInfo{}
dash, ok := obj.(*dashboardv1alpha1.Dashboard)
if ok {
dto.Dashboard = *dash
}
if access != nil {
err = b.scheme.Convert(access, &dto.Access, nil)
}
return dto, err
}); err != nil {
return err
}
apiGroupInfo.VersionedResourcesStorageMap[dashboardv1alpha1.VERSION] = storage
// v2alpha1
storage, err = b.storageForVersion(opts, legacyStore, largeObjects, func() runtime.Object {
return &dashboardv2alpha1.DashboardWithAccessInfo{}
})
if err != nil {
if err := b.storageForVersion(apiGroupInfo, opts, largeObjects,
dashboardv2alpha1.DashboardResourceInfo,
dashboardv2alpha1.LibraryPanelResourceInfo,
func(obj runtime.Object, access *dashboard.DashboardAccess) (v runtime.Object, err error) {
dto := &dashboardv2alpha1.DashboardWithAccessInfo{}
dash, ok := obj.(*dashboardv2alpha1.Dashboard)
if ok {
dto.Dashboard = *dash
}
if access != nil {
err = b.scheme.Convert(access, &dto.Access, nil)
}
return dto, err
}); err != nil {
return err
}
apiGroupInfo.VersionedResourcesStorageMap[dashboardv2alpha1.VERSION] = storage
return nil
}
func (b *DashboardsAPIBuilder) storageForVersion(
apiGroupInfo *genericapiserver.APIGroupInfo,
opts builder.APIGroupOptions,
legacyStore grafanarest.Storage,
largeObjects apistore.LargeObjectSupport,
newDTOFunc func() runtime.Object,
) (map[string]rest.Storage, error) {
var (
err error
scheme = opts.Scheme
dualWriteBuilder = opts.DualWriteBuilder
internalDashResourceInfo = dashboardinternal.DashboardResourceInfo
libraryPanelResourceInfo = dashboardinternal.LibraryPanelResourceInfo
)
dashboards utils.ResourceInfo,
libraryPanels utils.ResourceInfo,
newDTOFunc dtoBuilder,
) error {
// Register the versioned storage
storage := map[string]rest.Storage{}
storage[internalDashResourceInfo.StoragePath()] = legacyStore
apiGroupInfo.VersionedResourcesStorageMap[dashboards.GroupVersion().Version] = storage
// Dual writes if a RESTOptionsGetter is provided
if dualWriteBuilder != nil {
store, err := grafanaregistry.NewRegistryStore(scheme, internalDashResourceInfo, opts.OptsGetter)
if err != nil {
return nil, err
}
storage[internalDashResourceInfo.StoragePath()], err = dualWriteBuilder(internalDashResourceInfo.GroupResource(), legacyStore, store)
if err != nil {
return nil, err
}
legacyStore, err := b.legacy.NewStore(dashboards, opts.Scheme, opts.OptsGetter, b.reg)
if err != nil {
return err
}
store, err := grafanaregistry.NewRegistryStore(opts.Scheme, dashboards, opts.OptsGetter)
if err != nil {
return err
}
gr := dashboards.GroupResource()
storage[dashboards.StoragePath()], err = opts.DualWriteBuilder(gr, legacyStore, store)
if err != nil {
return err
}
if b.features.IsEnabledGlobally(featuremgmt.FlagKubernetesRestore) {
storage[internalDashResourceInfo.StoragePath("restore")] = NewRestoreConnector(
b.unified,
internalDashResourceInfo.GroupResource(),
)
storage[internalDashResourceInfo.StoragePath("latest")] = NewLatestConnector(
b.unified,
internalDashResourceInfo.GroupResource(),
)
storage[dashboards.StoragePath("restore")] = NewRestoreConnector(b.unified, gr)
storage[dashboards.StoragePath("latest")] = NewLatestConnector(b.unified, gr)
}
// Register the DTO endpoint that will consolidate all dashboard bits
storage[internalDashResourceInfo.StoragePath("dto")], err = NewDTOConnector(
storage[internalDashResourceInfo.StoragePath()],
storage[dashboards.StoragePath("dto")], err = NewDTOConnector(
storage[dashboards.StoragePath()].(rest.Getter),
largeObjects,
b.legacy.Access,
b.unified,
b.accessControl,
scheme,
opts.Scheme,
newDTOFunc,
)
if err != nil {
return nil, err
return err
}
// Expose read only library panels
storage[libraryPanelResourceInfo.StoragePath()] = &LibraryPanelStore{
storage[libraryPanels.StoragePath()] = &LibraryPanelStore{
Access: b.legacy.Access,
ResourceInfo: dashboardinternal.LibraryPanelResourceInfo,
ResourceInfo: libraryPanels,
}
return storage, nil
return nil
}
func (b *DashboardsAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions {
@ -326,7 +314,7 @@ func (b *DashboardsAPIBuilder) PostProcessOpenAPI(oas *spec3.OpenAPI) (*spec3.Op
for _, gv := range b.GetGroupVersions() {
version := gv.Version
// Hide cluster-scoped resources
root := path.Join("/apis/", dashboardinternal.GROUP, version)
root := path.Join("/apis/", dashboardv0alpha1.GROUP, version)
delete(oas.Paths.Paths, path.Join(root, "dashboards"))
delete(oas.Paths.Paths, path.Join(root, "watch", "dashboards"))

@ -22,7 +22,6 @@ import (
"github.com/grafana/grafana/pkg/storage/unified/search"
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/apis/dashboard"
dashboardv0alpha1 "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1"
folderv0alpha1 "github.com/grafana/grafana/pkg/apis/folder/v0alpha1"
"github.com/grafana/grafana/pkg/infra/log"
@ -44,7 +43,7 @@ type SearchHandler struct {
}
func NewSearchHandler(tracer trace.Tracer, dual dualwrite.Service, legacyDashboardSearcher resource.ResourceIndexClient, resourceClient resource.ResourceClient, features featuremgmt.FeatureToggles) *SearchHandler {
searchClient := resource.NewSearchClient(dual, dashboard.DashboardResourceInfo.GroupResource(), resourceClient, legacyDashboardSearcher)
searchClient := resource.NewSearchClient(dual, dashboardv0alpha1.DashboardResourceInfo.GroupResource(), resourceClient, legacyDashboardSearcher)
return &SearchHandler{
client: searchClient,
log: log.New("grafana-apiserver.dashboards.search"),
@ -263,7 +262,7 @@ func (s *SearchHandler) DoSearch(w http.ResponseWriter, r *http.Request) {
switch len(types) {
case 0:
// When no type specified, search for dashboards
searchRequest.Options.Key, err = asResourceKey(user.GetNamespace(), dashboard.DASHBOARD_RESOURCE)
searchRequest.Options.Key, err = asResourceKey(user.GetNamespace(), dashboardv0alpha1.DASHBOARD_RESOURCE)
// Currently a search query is across folders and dashboards
if err == nil {
federate, err = asResourceKey(user.GetNamespace(), folderv0alpha1.RESOURCE)
@ -425,7 +424,7 @@ func (s *SearchHandler) getDashboardsUIDsSharedWithUser(ctx context.Context, use
return sharedDashboards, nil
}
key, err := asResourceKey(user.GetNamespace(), dashboard.DASHBOARD_RESOURCE)
key, err := asResourceKey(user.GetNamespace(), dashboardv0alpha1.DASHBOARD_RESOURCE)
if err != nil {
return sharedDashboards, err
}

@ -10,10 +10,10 @@ import (
"k8s.io/apiserver/pkg/registry/rest"
claims "github.com/grafana/authlib/types"
"github.com/grafana/grafana-app-sdk/logging"
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/apimachinery/utils"
dashboard "github.com/grafana/grafana/pkg/apis/dashboard"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/apis/dashboard"
"github.com/grafana/grafana/pkg/infra/slugify"
"github.com/grafana/grafana/pkg/registry/apis/dashboard/legacy"
"github.com/grafana/grafana/pkg/services/accesscontrol"
@ -24,6 +24,8 @@ import (
"github.com/grafana/grafana/pkg/storage/unified/resource"
)
type dtoBuilder = func(dashboard runtime.Object, access *dashboard.DashboardAccess) (runtime.Object, error)
// The DTO returns everything the UI needs in a single request
type DTOConnector struct {
getter rest.Getter
@ -32,34 +34,27 @@ type DTOConnector struct {
largeObjects apistore.LargeObjectSupport
accessControl accesscontrol.AccessControl
scheme *runtime.Scheme
newFunc func() runtime.Object
log log.Logger
builder dtoBuilder
}
func NewDTOConnector(
dash rest.Storage,
getter rest.Getter,
largeObjects apistore.LargeObjectSupport,
legacyAccess legacy.DashboardAccess,
resourceClient resource.ResourceClient,
accessControl accesscontrol.AccessControl,
scheme *runtime.Scheme,
newFunc func() runtime.Object,
builder dtoBuilder,
) (rest.Storage, error) {
ok := false
v := &DTOConnector{
return &DTOConnector{
getter: getter,
legacy: legacyAccess,
accessControl: accessControl,
unified: resourceClient,
largeObjects: largeObjects,
newFunc: newFunc,
builder: builder,
scheme: scheme,
log: log.New("grafana-apiserver.dashboards.dto-connector"),
}
v.getter, ok = dash.(rest.Getter)
if !ok {
return nil, fmt.Errorf("dashboard storage must implement getter")
}
return v, nil
}, nil
}
var (
@ -68,7 +63,8 @@ var (
)
func (r *DTOConnector) New() runtime.Object {
return r.newFunc()
obj, _ := r.builder(nil, nil)
return obj
}
func (r *DTOConnector) Destroy() {
@ -79,7 +75,7 @@ func (r *DTOConnector) ConnectMethods() []string {
}
func (r *DTOConnector) NewConnectOptions() (runtime.Object, bool, string) {
return &dashboard.VersionsQueryOptions{}, false, ""
return nil, false, ""
}
func (r *DTOConnector) ProducesMIMETypes(verb string) []string {
@ -87,7 +83,7 @@ func (r *DTOConnector) ProducesMIMETypes(verb string) []string {
}
func (r *DTOConnector) ProducesObject(verb string) interface{} {
return r.newFunc()
return r.New()
}
func (r *DTOConnector) Connect(ctx context.Context, name string, opts runtime.Object, responder rest.Responder) (http.Handler, error) {
@ -105,50 +101,11 @@ func (r *DTOConnector) Connect(ctx context.Context, name string, opts runtime.Ob
if err != nil {
return nil, err
}
dash, err := ToInternalDashboard(r.scheme, rawobj)
if err != nil {
return nil, err
}
obj, err := utils.MetaAccessor(dash)
obj, err := utils.MetaAccessor(rawobj)
if err != nil {
return nil, err
}
dto := &dashboards.Dashboard{
UID: name,
OrgID: info.OrgID,
ID: obj.GetDeprecatedInternalID(), // nolint:staticcheck
}
repo, err := obj.GetRepositoryInfo()
if err != nil {
return nil, err
}
if repo != nil && repo.Name == dashboard.PluginIDRepoName {
dto.PluginID = repo.Path
}
guardian, err := guardian.NewByDashboard(ctx, dto, info.OrgID, user)
if err != nil {
return nil, err
}
canView, err := guardian.CanView()
if err != nil || !canView {
return nil, fmt.Errorf("not allowed to view")
}
access := dashboard.DashboardAccess{}
access.CanEdit, _ = guardian.CanEdit()
access.CanSave, _ = guardian.CanSave()
access.CanAdmin, _ = guardian.CanAdmin()
access.CanDelete, _ = guardian.CanDelete()
access.CanStar = user.IsIdentityType(claims.TypeUser)
access.AnnotationsPermissions = &dashboard.AnnotationPermission{}
r.getAnnotationPermissionsByScope(ctx, user, &access.AnnotationsPermissions.Dashboard, accesscontrol.ScopeAnnotationsTypeDashboard)
r.getAnnotationPermissionsByScope(ctx, user, &access.AnnotationsPermissions.Organization, accesscontrol.ScopeAnnotationsTypeOrganization)
// Check for blob info
blobInfo := obj.GetBlob()
if blobInfo != nil && r.largeObjects != nil {
@ -164,35 +121,84 @@ func (r *DTOConnector) Connect(ctx context.Context, name string, opts runtime.Ob
}
}
access.Slug = slugify.Slugify(dash.Spec.GetNestedString("title"))
access.Url = dashboards.GetDashboardFolderURL(false, name, access.Slug)
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
responder.Object(http.StatusOK, &dashboard.DashboardWithAccessInfo{
Dashboard: *dash,
Access: access,
})
// Skip the access info and return the dashboard that may be loaded with large object support
if req.URL.Query().Get("includeAccess") == "false" {
responder.Object(200, rawobj)
return
}
// Calculate access information -- needed to help smooth transition from /api/dashboard format
dto := &dashboards.Dashboard{
UID: name,
OrgID: info.OrgID,
ID: obj.GetDeprecatedInternalID(), // nolint:staticcheck
}
repo, err := obj.GetRepositoryInfo()
if err != nil {
responder.Error(err)
return
}
if repo != nil && repo.Name == dashboard.PluginIDRepoName {
dto.PluginID = repo.Path
}
guardian, err := guardian.NewByDashboard(ctx, dto, info.OrgID, user)
if err != nil {
responder.Error(err)
return
}
canView, err := guardian.CanView()
if err != nil || !canView {
responder.Error(fmt.Errorf("not allowed to view"))
return
}
access := &dashboard.DashboardAccess{}
access.CanEdit, _ = guardian.CanEdit()
access.CanSave, _ = guardian.CanSave()
access.CanAdmin, _ = guardian.CanAdmin()
access.CanDelete, _ = guardian.CanDelete()
access.CanStar = user.IsIdentityType(claims.TypeUser)
access.AnnotationsPermissions = &dashboard.AnnotationPermission{}
r.getAnnotationPermissionsByScope(ctx, user, &access.AnnotationsPermissions.Dashboard, accesscontrol.ScopeAnnotationsTypeDashboard)
r.getAnnotationPermissionsByScope(ctx, user, &access.AnnotationsPermissions.Organization, accesscontrol.ScopeAnnotationsTypeOrganization)
// FIXME!!!! does not get the title!
// The title property next to unstructured and not found in this model
title := obj.FindTitle("")
access.Slug = slugify.Slugify(title)
access.Url = dashboards.GetDashboardFolderURL(false, name, access.Slug)
dash, err := r.builder(rawobj, access)
if err != nil {
responder.Error(err)
return
}
responder.Object(http.StatusOK, dash)
}), nil
}
func (r *DTOConnector) getAnnotationPermissionsByScope(ctx context.Context, user identity.Requester, actions *dashboard.AnnotationActions, scope string) {
var err error
logger := logging.FromContext(ctx).With("logger", "dto-connector")
evaluate := accesscontrol.EvalPermission(accesscontrol.ActionAnnotationsCreate, scope)
actions.CanAdd, err = r.accessControl.Evaluate(ctx, user, evaluate)
if err != nil {
r.log.Warn("Failed to evaluate permission", "err", err, "action", accesscontrol.ActionAnnotationsCreate, "scope", scope)
logger.Warn("Failed to evaluate permission", "err", err, "action", accesscontrol.ActionAnnotationsCreate, "scope", scope)
}
evaluate = accesscontrol.EvalPermission(accesscontrol.ActionAnnotationsDelete, scope)
actions.CanDelete, err = r.accessControl.Evaluate(ctx, user, evaluate)
if err != nil {
r.log.Warn("Failed to evaluate permission", "err", err, "action", accesscontrol.ActionAnnotationsDelete, "scope", scope)
logger.Warn("Failed to evaluate permission", "err", err, "action", accesscontrol.ActionAnnotationsDelete, "scope", scope)
}
evaluate = accesscontrol.EvalPermission(accesscontrol.ActionAnnotationsWrite, scope)
actions.CanEdit, err = r.accessControl.Evaluate(ctx, user, evaluate)
if err != nil {
r.log.Warn("Failed to evaluate permission", "err", err, "action", accesscontrol.ActionAnnotationsWrite, "scope", scope)
logger.Warn("Failed to evaluate permission", "err", err, "action", accesscontrol.ActionAnnotationsWrite, "scope", scope)
}
}

@ -486,6 +486,7 @@ func saveDashboard(sess *db.Session, cmd *dashboards.SaveDashboardCommand, emitE
CreatedBy: dash.UpdatedBy,
Message: cmd.Message,
Data: dash.Data,
APIVersion: cmd.APIVersion,
}
// insert version entry

@ -26,13 +26,14 @@ const (
// Dashboard model
type Dashboard struct {
ID int64 `xorm:"pk autoincr 'id'"`
UID string `xorm:"uid"`
Slug string
OrgID int64 `xorm:"org_id"`
GnetID int64 `xorm:"gnet_id"`
Version int
PluginID string `xorm:"plugin_id"`
ID int64 `xorm:"pk autoincr 'id'"`
UID string `xorm:"uid"`
Slug string
OrgID int64 `xorm:"org_id"`
GnetID int64 `xorm:"gnet_id"`
Version int
PluginID string `xorm:"plugin_id"`
APIVersion string `xorm:"api_version"`
Created time.Time
Updated time.Time
@ -138,6 +139,7 @@ func (cmd *SaveDashboardCommand) GetDashboardModel() *Dashboard {
dash.OrgID = cmd.OrgID
dash.PluginID = cmd.PluginID
dash.IsFolder = cmd.IsFolder
dash.APIVersion = cmd.APIVersion
metrics.MFolderIDsServiceCount.WithLabelValues(metrics.Dashboard).Inc()
// nolint:staticcheck
dash.FolderID = cmd.FolderID
@ -202,6 +204,8 @@ type SaveDashboardCommand struct {
OrgID int64 `json:"-" xorm:"org_id"`
RestoredFrom int `json:"-"`
PluginID string `json:"-" xorm:"plugin_id"`
APIVersion string `json:"-" xorm:"api_version"`
// Deprecated: use FolderUID instead
FolderID int64 `json:"folderId" xorm:"folder_id"`
FolderUID string `json:"folderUid" xorm:"folder_uid"`

@ -1787,13 +1787,13 @@ func (dr *DashboardServiceImpl) searchDashboardsThroughK8sRaw(ctx context.Contex
switch query.Type {
case "":
// When no type specified, search for dashboards
request.Options.Key, err = resource.AsResourceKey(namespace, dashboard.DASHBOARD_RESOURCE)
request.Options.Key, err = resource.AsResourceKey(namespace, dashboardv0alpha1.DASHBOARD_RESOURCE)
// Currently a search query is across folders and dashboards
if err == nil {
federate, err = resource.AsResourceKey(namespace, folderv0alpha1.RESOURCE)
}
case searchstore.TypeDashboard, searchstore.TypeAnnotation:
request.Options.Key, err = resource.AsResourceKey(namespace, dashboard.DASHBOARD_RESOURCE)
request.Options.Key, err = resource.AsResourceKey(namespace, dashboardv0alpha1.DASHBOARD_RESOURCE)
case searchstore.TypeFolder, searchstore.TypeAlertFolder:
request.Options.Key, err = resource.AsResourceKey(namespace, folderv0alpha1.RESOURCE)
default:
@ -1954,13 +1954,14 @@ func (dr *DashboardServiceImpl) UnstructuredToLegacyDashboard(ctx context.Contex
}
out := dashboards.Dashboard{
OrgID: orgID,
ID: obj.GetDeprecatedInternalID(), // nolint:staticcheck
UID: uid,
Slug: obj.GetSlug(),
FolderUID: obj.GetFolder(),
Version: dashVersion,
Data: simplejson.NewFromAny(spec),
OrgID: orgID,
ID: obj.GetDeprecatedInternalID(), // nolint:staticcheck
UID: uid,
Slug: obj.GetSlug(),
FolderUID: obj.GetFolder(),
Version: dashVersion,
Data: simplejson.NewFromAny(spec),
APIVersion: strings.TrimPrefix(item.GetAPIVersion(), dashboardv0alpha1.GROUP+"/"),
}
out.Created = obj.GetCreationTimestamp().Time

@ -17,11 +17,12 @@ var (
// fixtures that insert DashboardVersions directly into a database which must be
// refactored first.
type DashboardVersion struct {
ID int64 `json:"id" xorm:"pk autoincr 'id'" db:"id"`
DashboardID int64 `json:"dashboardId" xorm:"dashboard_id" db:"dashboard_id"`
ParentVersion int `json:"parentVersion" db:"parent_version"`
RestoredFrom int `json:"restoredFrom" db:"restored_from"`
Version int `json:"version" db:"version"`
ID int64 `json:"id" xorm:"pk autoincr 'id'" db:"id"`
DashboardID int64 `json:"dashboardId" xorm:"dashboard_id" db:"dashboard_id"`
ParentVersion int `json:"parentVersion" db:"parent_version"`
RestoredFrom int `json:"restoredFrom" db:"restored_from"`
Version int `json:"version" db:"version"`
APIVersion string `json:"apiVersion" xorm:"api_version" db:"api_version"`
Created time.Time `json:"created" db:"created"`
CreatedBy int64 `json:"createdBy" db:"created_by"`

@ -6,7 +6,7 @@ import (
"os"
"time"
"github.com/grafana/grafana/pkg/apis/dashboard"
dashboard "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/folder"

@ -3,8 +3,9 @@ package migrations
import (
"fmt"
. "github.com/grafana/grafana/pkg/services/sqlstore/migrator"
"xorm.io/xorm"
. "github.com/grafana/grafana/pkg/services/sqlstore/migrator"
)
func addDashboardMigration(mg *Migrator) {
@ -256,6 +257,10 @@ func addDashboardMigration(mg *Migrator) {
}))
mg.AddMigration("Add missing dashboard_uid and org_id to dashboard_tag", &FillDashbordUIDAndOrgIDMigration{})
mg.AddMigration("Add apiVersion for dashboard", NewAddColumnMigration(dashboardV2, &Column{
Name: "api_version", Type: DB_Varchar, Length: 16, Nullable: true,
}))
}
type FillDashbordUIDAndOrgIDMigration struct {

@ -56,4 +56,8 @@ FROM dashboard;`
// change column type of dashboard_version.data
mg.AddMigration("alter dashboard_version.data to mediumtext v1", NewRawSQLMigration("").
Mysql("ALTER TABLE dashboard_version MODIFY data MEDIUMTEXT;"))
mg.AddMigration("Add apiVersion for dashboard_version", NewAddColumnMigration(dashboardVersionV1, &Column{
Name: "api_version", Type: DB_Varchar, Length: 16, Nullable: true,
}))
}

@ -4,7 +4,7 @@ import (
"golang.org/x/net/context"
"k8s.io/apimachinery/pkg/runtime/schema"
dashboard "github.com/grafana/grafana/pkg/apis/dashboard"
dashboard "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1"
folders "github.com/grafana/grafana/pkg/apis/folder/v0alpha1"
)

@ -10,14 +10,15 @@ import (
"sync"
"time"
dashboardv0alpha1 "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1"
folderv0alpha1 "github.com/grafana/grafana/pkg/apis/folder/v0alpha1"
"github.com/hashicorp/golang-lru/v2/expirable"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
"golang.org/x/sync/errgroup"
"k8s.io/apimachinery/pkg/runtime/schema"
dashboardv0alpha1 "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1"
folderv0alpha1 "github.com/grafana/grafana/pkg/apis/folder/v0alpha1"
"github.com/grafana/authlib/types"
)
@ -685,7 +686,7 @@ func AsResourceKey(ns string, t string) (*ResourceKey, error) {
return &ResourceKey{
Namespace: ns,
Group: dashboardv0alpha1.GROUP,
Resource: dashboardv0alpha1.RESOURCE,
Resource: dashboardv0alpha1.DASHBOARD_RESOURCE,
}, nil
// NOT really supported in the dashboard search UI, but useful for manual testing

@ -9,12 +9,18 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/dynamic"
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/apimachinery/utils"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/tests/apis"
"github.com/grafana/grafana/pkg/tests/testinfra"
"github.com/grafana/grafana/pkg/tests/testsuite"
dashboardV0 "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1"
dashboardV1 "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1"
dashboardV2 "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1"
)
func TestMain(m *testing.M) {
@ -40,6 +46,8 @@ func runDashboardTest(t *testing.T, helper *apis.K8sTestHelper, gvr schema.Group
},
}
obj.SetGenerateName("aa")
obj.SetAPIVersion(gvr.GroupVersion().String())
obj.SetKind("Dashboard")
obj, err = client.Resource.Create(ctx, obj, metav1.CreateOptions{})
require.NoError(t, err)
created := obj.GetName()
@ -241,3 +249,93 @@ func TestIntegrationDashboardsAppV1Alpha1(t *testing.T) {
runDashboardTest(t, helper, gvr)
})
}
func TestIntegrationLegacySupport(t *testing.T) {
ctx := context.Background()
helper := apis.NewK8sTestHelper(t, testinfra.GrafanaOpts{
EnableFeatureToggles: []string{
// NOTE: when using this feature toggle, the read is always v0!
// featuremgmt.FlagKubernetesClientDashboardsFolders
},
})
clientV0 := helper.GetResourceClient(apis.ResourceClientArgs{
User: helper.Org1.Admin,
GVR: dashboardV0.DashboardResourceInfo.GroupVersionResource(),
})
obj, err := clientV0.Resource.Create(ctx,
helper.LoadYAMLOrJSONFile("testdata/dashboard-test-v0.yaml"),
metav1.CreateOptions{},
)
require.NoError(t, err)
require.Equal(t, "test-v0", obj.GetName())
clientV1 := helper.GetResourceClient(apis.ResourceClientArgs{
User: helper.Org1.Admin,
GVR: dashboardV1.DashboardResourceInfo.GroupVersionResource(),
})
obj, err = clientV1.Resource.Create(ctx,
helper.LoadYAMLOrJSONFile("testdata/dashboard-test-v1.yaml"),
metav1.CreateOptions{},
)
require.NoError(t, err)
require.Equal(t, "test-v1", obj.GetName())
clientV2 := helper.GetResourceClient(apis.ResourceClientArgs{
User: helper.Org1.Admin,
GVR: dashboardV2.DashboardResourceInfo.GroupVersionResource(),
})
obj, err = clientV2.Resource.Create(ctx,
helper.LoadYAMLOrJSONFile("testdata/dashboard-test-v2.yaml"),
metav1.CreateOptions{},
)
require.NoError(t, err)
require.Equal(t, "test-v2", obj.GetName())
//---------------------------------------------------------
// Now check that we can get each dashboard with any API
//---------------------------------------------------------
names := []string{"test-v0", "test-v1", "test-v2"}
clients := []dynamic.ResourceInterface{
clientV0.Resource,
clientV1.Resource,
clientV2.Resource,
}
for _, name := range names {
for _, client := range clients {
obj, err := client.Get(ctx, name, metav1.GetOptions{})
require.NoError(t, err)
require.Equal(t, name, obj.GetName())
// Can get the same thing with the /dto endpoint
obj, err = client.Get(ctx, name, metav1.GetOptions{}, "dto")
require.NoError(t, err)
require.Equal(t, name, obj.GetName())
}
}
//---------------------------------------------------------
// Check that the legacy APIs return the correct apiVersion
//---------------------------------------------------------
rsp := apis.DoRequest(helper, apis.RequestParams{
User: helper.Org1.Admin,
Path: "/api/dashboards/uid/test-v0",
}, &dtos.DashboardFullWithMeta{})
require.Equal(t, 200, rsp.Response.StatusCode)
require.Equal(t, "v0alpha1", rsp.Result.Meta.APIVersion)
rsp = apis.DoRequest(helper, apis.RequestParams{
User: helper.Org1.Admin,
Path: "/api/dashboards/uid/test-v1",
}, &dtos.DashboardFullWithMeta{})
require.Equal(t, 200, rsp.Response.StatusCode)
require.Equal(t, "v1alpha1", rsp.Result.Meta.APIVersion)
// V2 should send a redirect
rsp = apis.DoRequest(helper, apis.RequestParams{
User: helper.Org1.Admin,
Path: "/api/dashboards/uid/test-v2",
}, &dtos.DashboardFullWithMeta{})
require.Equal(t, 302, rsp.Response.StatusCode) // redirect
}

@ -1,6 +1,6 @@
apiVersion: dashboard.grafana.app/v0alpha1
kind: Dashboard
metadata:
name: test
name: test-v0
spec:
title: Test dashboard (apply from k8s; PATCH) X
title: Test dashboard. Created at v0

@ -0,0 +1,6 @@
apiVersion: dashboard.grafana.app/v1alpha1
kind: Dashboard
metadata:
name: test-v1
spec:
title: Test dashboard. Created at v1 XXX

@ -0,0 +1,6 @@
apiVersion: dashboard.grafana.app/v2alpha1
kind: Dashboard
metadata:
name: test-v2
spec:
title: Test dashboard. Created at v2

@ -385,7 +385,12 @@ func DoRequest[T any](c *K8sTestHelper, params RequestParams, result *T) K8sResp
if params.Accept != "" {
req.Header.Set("Accept", params.Accept)
}
rsp, err := http.DefaultClient.Do(req)
client := &http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}
rsp, err := client.Do(req)
require.NoError(c.t, err)
r := K8sResponse[T]{

@ -1058,22 +1058,6 @@
"type": "string",
"uniqueItems": true
}
},
{
"name": "path",
"in": "query",
"schema": {
"type": "string",
"uniqueItems": true
}
},
{
"name": "version",
"in": "query",
"schema": {
"type": "integer",
"uniqueItems": true
}
}
]
},
@ -1652,6 +1636,20 @@
}
}
},
"com.github.grafana.grafana.pkg.apis.dashboard.v0alpha1.ConversionStatus": {
"type": "object",
"properties": {
"error": {
"type": "string"
},
"failed": {
"type": "boolean"
},
"storedVersion": {
"type": "string"
}
}
},
"com.github.grafana.grafana.pkg.apis.dashboard.v0alpha1.Dashboard": {
"type": "object",
"required": [
@ -1682,6 +1680,14 @@
"$ref": "#/components/schemas/com.github.grafana.grafana.pkg.apimachinery.apis.common.v0alpha1.Unstructured"
}
]
},
"status": {
"description": "Optional dashboard status",
"allOf": [
{
"$ref": "#/components/schemas/com.github.grafana.grafana.pkg.apis.dashboard.v0alpha1.DashboardStatus"
}
]
}
},
"x-kubernetes-group-version-kind": [
@ -1776,6 +1782,14 @@
}
]
},
"com.github.grafana.grafana.pkg.apis.dashboard.v0alpha1.DashboardStatus": {
"type": "object",
"properties": {
"conversion": {
"$ref": "#/components/schemas/com.github.grafana.grafana.pkg.apis.dashboard.v0alpha1.ConversionStatus"
}
}
},
"com.github.grafana.grafana.pkg.apis.dashboard.v0alpha1.DashboardWithAccessInfo": {
"description": "This is like the legacy DTO where access and metadata are all returned in a single call",
"type": "object",
@ -1816,6 +1830,14 @@
"$ref": "#/components/schemas/com.github.grafana.grafana.pkg.apimachinery.apis.common.v0alpha1.Unstructured"
}
]
},
"status": {
"description": "Optional dashboard status",
"allOf": [
{
"$ref": "#/components/schemas/com.github.grafana.grafana.pkg.apis.dashboard.v0alpha1.DashboardStatus"
}
]
}
},
"x-kubernetes-group-version-kind": [

@ -14530,6 +14530,9 @@
"annotationsPermissions": {
"$ref": "#/definitions/AnnotationPermission"
},
"apiVersion": {
"type": "string"
},
"canAdmin": {
"type": "boolean"
},

@ -272,6 +272,7 @@ export type AnnotationPermission = {
};
export type DashboardMeta = {
annotationsPermissions?: AnnotationPermission;
apiVersion?: string;
canAdmin?: boolean;
canDelete?: boolean;
canEdit?: boolean;

@ -4585,6 +4585,9 @@
"annotationsPermissions": {
"$ref": "#/components/schemas/AnnotationPermission"
},
"apiVersion": {
"type": "string"
},
"canAdmin": {
"type": "boolean"
},

Loading…
Cancel
Save