|
|
|
@@ -1,14 +1,12 @@
|
|
|
|
|
package conversion
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
|
|
"k8s.io/apimachinery/pkg/conversion"
|
|
|
|
|
|
|
|
|
|
dashv1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v1beta1"
|
|
|
|
|
dashv2alpha1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1"
|
|
|
|
|
"github.com/grafana/grafana/apps/dashboard/pkg/migration/schemaversion"
|
|
|
|
|
"k8s.io/apimachinery/pkg/conversion"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// ConvertDashboard_V2alpha1_to_V1beta1 converts a v2alpha1 dashboard to v1beta1 format.
|
|
|
|
@@ -16,19 +14,13 @@ import (
|
|
|
|
|
// that represents the v1 dashboard JSON format.
|
|
|
|
|
// The dsIndexProvider is used to resolve default datasources when queries/variables/annotations
|
|
|
|
|
// don't have explicit datasource references.
|
|
|
|
|
func ConvertDashboard_V2alpha1_to_V1beta1(in *dashv2alpha1.Dashboard, out *dashv1.Dashboard, scope conversion.Scope, dsIndexProvider schemaversion.DataSourceIndexProvider) error {
|
|
|
|
|
func ConvertDashboard_V2alpha1_to_V1beta1(in *dashv2alpha1.Dashboard, out *dashv1.Dashboard, scope conversion.Scope) error {
|
|
|
|
|
out.ObjectMeta = in.ObjectMeta
|
|
|
|
|
out.APIVersion = dashv1.APIVERSION
|
|
|
|
|
out.Kind = in.Kind // Preserve the Kind from input (should be "Dashboard")
|
|
|
|
|
|
|
|
|
|
// Get datasource index for resolving default datasources
|
|
|
|
|
var dsIndex *schemaversion.DatasourceIndex
|
|
|
|
|
if dsIndexProvider != nil {
|
|
|
|
|
dsIndex = dsIndexProvider.Index(context.Background())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Convert the spec to v1beta1 unstructured format
|
|
|
|
|
dashboardJSON, err := convertDashboardSpec_V2alpha1_to_V1beta1(&in.Spec, dsIndex)
|
|
|
|
|
dashboardJSON, err := convertDashboardSpec_V2alpha1_to_V1beta1(&in.Spec)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("failed to convert dashboard spec: %w", err)
|
|
|
|
|
}
|
|
|
|
@@ -39,7 +31,7 @@ func ConvertDashboard_V2alpha1_to_V1beta1(in *dashv2alpha1.Dashboard, out *dashv
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func convertDashboardSpec_V2alpha1_to_V1beta1(in *dashv2alpha1.DashboardSpec, dsIndex *schemaversion.DatasourceIndex) (map[string]interface{}, error) {
|
|
|
|
|
func convertDashboardSpec_V2alpha1_to_V1beta1(in *dashv2alpha1.DashboardSpec) (map[string]interface{}, error) {
|
|
|
|
|
dashboard := make(map[string]interface{})
|
|
|
|
|
|
|
|
|
|
// Convert basic fields
|
|
|
|
@@ -75,7 +67,7 @@ func convertDashboardSpec_V2alpha1_to_V1beta1(in *dashv2alpha1.DashboardSpec, ds
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Convert panels from elements and layout
|
|
|
|
|
panels, err := convertPanelsFromElementsAndLayout(in.Elements, in.Layout, dsIndex)
|
|
|
|
|
panels, err := convertPanelsFromElementsAndLayout(in.Elements, in.Layout)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("failed to convert panels: %w", err)
|
|
|
|
|
}
|
|
|
|
@@ -90,7 +82,7 @@ func convertDashboardSpec_V2alpha1_to_V1beta1(in *dashv2alpha1.DashboardSpec, ds
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Convert variables
|
|
|
|
|
variables := convertVariablesToV1(in.Variables, dsIndex)
|
|
|
|
|
variables := convertVariablesToV1(in.Variables)
|
|
|
|
|
if len(variables) > 0 {
|
|
|
|
|
dashboard["templating"] = map[string]interface{}{
|
|
|
|
|
"list": variables,
|
|
|
|
@@ -98,7 +90,7 @@ func convertDashboardSpec_V2alpha1_to_V1beta1(in *dashv2alpha1.DashboardSpec, ds
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Convert annotations - always include even if empty to prevent DashboardModel from adding built-in
|
|
|
|
|
annotations := convertAnnotationsToV1(in.Annotations, dsIndex)
|
|
|
|
|
annotations := convertAnnotationsToV1(in.Annotations)
|
|
|
|
|
dashboard["annotations"] = map[string]interface{}{
|
|
|
|
|
"list": annotations,
|
|
|
|
|
}
|
|
|
|
@@ -236,28 +228,28 @@ func countTotalPanels(panels []interface{}) int {
|
|
|
|
|
// - RowsLayout: Rows become row panels; nested structures are flattened
|
|
|
|
|
// - AutoGridLayout: Calculates gridPos based on column count and row height
|
|
|
|
|
// - TabsLayout: Tabs become expanded row panels; content is flattened
|
|
|
|
|
func convertPanelsFromElementsAndLayout(elements map[string]dashv2alpha1.DashboardElement, layout dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind, dsIndex *schemaversion.DatasourceIndex) ([]interface{}, error) {
|
|
|
|
|
func convertPanelsFromElementsAndLayout(elements map[string]dashv2alpha1.DashboardElement, layout dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind) ([]interface{}, error) {
|
|
|
|
|
if layout.GridLayoutKind != nil {
|
|
|
|
|
return convertGridLayoutToPanels(elements, layout.GridLayoutKind, dsIndex)
|
|
|
|
|
return convertGridLayoutToPanels(elements, layout.GridLayoutKind)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if layout.RowsLayoutKind != nil {
|
|
|
|
|
return convertRowsLayoutToPanels(elements, layout.RowsLayoutKind, dsIndex)
|
|
|
|
|
return convertRowsLayoutToPanels(elements, layout.RowsLayoutKind)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if layout.AutoGridLayoutKind != nil {
|
|
|
|
|
return convertAutoGridLayoutToPanels(elements, layout.AutoGridLayoutKind, dsIndex)
|
|
|
|
|
return convertAutoGridLayoutToPanels(elements, layout.AutoGridLayoutKind)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if layout.TabsLayoutKind != nil {
|
|
|
|
|
return convertTabsLayoutToPanels(elements, layout.TabsLayoutKind, dsIndex)
|
|
|
|
|
return convertTabsLayoutToPanels(elements, layout.TabsLayoutKind)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// No layout specified, return empty panels
|
|
|
|
|
return []interface{}{}, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func convertGridLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, gridLayout *dashv2alpha1.DashboardGridLayoutKind, dsIndex *schemaversion.DatasourceIndex) ([]interface{}, error) {
|
|
|
|
|
func convertGridLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, gridLayout *dashv2alpha1.DashboardGridLayoutKind) ([]interface{}, error) {
|
|
|
|
|
panels := make([]interface{}, 0, len(gridLayout.Spec.Items))
|
|
|
|
|
|
|
|
|
|
for _, item := range gridLayout.Spec.Items {
|
|
|
|
@@ -266,7 +258,7 @@ func convertGridLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement
|
|
|
|
|
return nil, fmt.Errorf("panel with uid %s not found in the dashboard elements", item.Spec.Element.Name)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
panel, err := convertPanelFromElement(&element, &item, dsIndex)
|
|
|
|
|
panel, err := convertPanelFromElement(&element, &item)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("failed to convert panel %s: %w", item.Spec.Element.Name, err)
|
|
|
|
|
}
|
|
|
|
@@ -279,21 +271,21 @@ func convertGridLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement
|
|
|
|
|
// convertRowsLayoutToPanels converts a RowsLayout to V1 panels.
|
|
|
|
|
// All nested structures (rows within rows, tabs within rows) are flattened to the root level.
|
|
|
|
|
// Each row becomes a row panel, and nested content is added sequentially after it.
|
|
|
|
|
func convertRowsLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, rowsLayout *dashv2alpha1.DashboardRowsLayoutKind, dsIndex *schemaversion.DatasourceIndex) ([]interface{}, error) {
|
|
|
|
|
return convertNestedLayoutToPanels(elements, rowsLayout, nil, dsIndex, 0)
|
|
|
|
|
func convertRowsLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, rowsLayout *dashv2alpha1.DashboardRowsLayoutKind) ([]interface{}, error) {
|
|
|
|
|
return convertNestedLayoutToPanels(elements, rowsLayout, nil, 0)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// convertNestedLayoutToPanels handles arbitrary nesting of RowsLayout and TabsLayout.
|
|
|
|
|
// It processes each row/tab in order, tracking Y position to ensure panels don't overlap.
|
|
|
|
|
// The function recursively flattens nested structures to produce a flat V1 panel array.
|
|
|
|
|
func convertNestedLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, rowsLayout *dashv2alpha1.DashboardRowsLayoutKind, tabsLayout *dashv2alpha1.DashboardTabsLayoutKind, dsIndex *schemaversion.DatasourceIndex, yOffset int64) ([]interface{}, error) {
|
|
|
|
|
func convertNestedLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, rowsLayout *dashv2alpha1.DashboardRowsLayoutKind, tabsLayout *dashv2alpha1.DashboardTabsLayoutKind, yOffset int64) ([]interface{}, error) {
|
|
|
|
|
panels := make([]interface{}, 0)
|
|
|
|
|
currentY := yOffset
|
|
|
|
|
|
|
|
|
|
// Process RowsLayout
|
|
|
|
|
if rowsLayout != nil {
|
|
|
|
|
for _, row := range rowsLayout.Spec.Rows {
|
|
|
|
|
rowPanels, newY, err := processRowItem(elements, &row, dsIndex, currentY)
|
|
|
|
|
rowPanels, newY, err := processRowItem(elements, &row, currentY)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
@@ -305,7 +297,7 @@ func convertNestedLayoutToPanels(elements map[string]dashv2alpha1.DashboardEleme
|
|
|
|
|
// Process TabsLayout (tabs are converted to rows)
|
|
|
|
|
if tabsLayout != nil {
|
|
|
|
|
for _, tab := range tabsLayout.Spec.Tabs {
|
|
|
|
|
tabPanels, newY, err := processTabItem(elements, &tab, dsIndex, currentY)
|
|
|
|
|
tabPanels, newY, err := processTabItem(elements, &tab, currentY)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
@@ -324,7 +316,7 @@ func convertNestedLayoutToPanels(elements map[string]dashv2alpha1.DashboardEleme
|
|
|
|
|
// - Collapsed row: Panels stored inside row.panels with absolute Y positions
|
|
|
|
|
// - Expanded row: Panels added to top level after the row panel
|
|
|
|
|
// - Nested layouts: Parent row is preserved; nested content is flattened after it
|
|
|
|
|
func processRowItem(elements map[string]dashv2alpha1.DashboardElement, row *dashv2alpha1.DashboardRowsLayoutRowKind, dsIndex *schemaversion.DatasourceIndex, startY int64) ([]interface{}, int64, error) {
|
|
|
|
|
func processRowItem(elements map[string]dashv2alpha1.DashboardElement, row *dashv2alpha1.DashboardRowsLayoutRowKind, startY int64) ([]interface{}, int64, error) {
|
|
|
|
|
panels := make([]interface{}, 0)
|
|
|
|
|
currentY := startY
|
|
|
|
|
|
|
|
|
@@ -354,7 +346,7 @@ func processRowItem(elements map[string]dashv2alpha1.DashboardElement, row *dash
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Then process nested rows
|
|
|
|
|
nestedPanels, err := convertNestedLayoutToPanels(elements, row.Spec.Layout.RowsLayoutKind, nil, dsIndex, currentY)
|
|
|
|
|
nestedPanels, err := convertNestedLayoutToPanels(elements, row.Spec.Layout.RowsLayoutKind, nil, currentY)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, 0, err
|
|
|
|
|
}
|
|
|
|
@@ -387,7 +379,7 @@ func processRowItem(elements map[string]dashv2alpha1.DashboardElement, row *dash
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Then process nested tabs
|
|
|
|
|
nestedPanels, err := convertNestedLayoutToPanels(elements, nil, row.Spec.Layout.TabsLayoutKind, dsIndex, currentY)
|
|
|
|
|
nestedPanels, err := convertNestedLayoutToPanels(elements, nil, row.Spec.Layout.TabsLayoutKind, currentY)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, 0, err
|
|
|
|
|
}
|
|
|
|
@@ -429,7 +421,7 @@ func processRowItem(elements map[string]dashv2alpha1.DashboardElement, row *dash
|
|
|
|
|
|
|
|
|
|
// Add collapsed panels if row is collapsed (panels use absolute Y positions)
|
|
|
|
|
if isCollapsed {
|
|
|
|
|
collapsedPanels, err := extractCollapsedPanelsWithAbsoluteY(elements, &row.Spec.Layout, dsIndex, currentY+1)
|
|
|
|
|
collapsedPanels, err := extractCollapsedPanelsWithAbsoluteY(elements, &row.Spec.Layout, currentY+1)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, 0, err
|
|
|
|
|
}
|
|
|
|
@@ -444,7 +436,7 @@ func processRowItem(elements map[string]dashv2alpha1.DashboardElement, row *dash
|
|
|
|
|
|
|
|
|
|
// Add panels from row layout (only for expanded rows or hidden header rows)
|
|
|
|
|
if !isCollapsed || isHiddenHeader {
|
|
|
|
|
rowPanels, newY, err := extractExpandedPanels(elements, &row.Spec.Layout, dsIndex, currentY, isHiddenHeader, startY)
|
|
|
|
|
rowPanels, newY, err := extractExpandedPanels(elements, &row.Spec.Layout, currentY, isHiddenHeader, startY)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, 0, err
|
|
|
|
|
}
|
|
|
|
@@ -459,7 +451,7 @@ func processRowItem(elements map[string]dashv2alpha1.DashboardElement, row *dash
|
|
|
|
|
// Each tab becomes an expanded row panel (collapsed=false) with an empty panels array.
|
|
|
|
|
// The tab's content is flattened and added to the top level after the row panel.
|
|
|
|
|
// Nested layouts within the tab are recursively processed.
|
|
|
|
|
func processTabItem(elements map[string]dashv2alpha1.DashboardElement, tab *dashv2alpha1.DashboardTabsLayoutTabKind, dsIndex *schemaversion.DatasourceIndex, startY int64) ([]interface{}, int64, error) {
|
|
|
|
|
func processTabItem(elements map[string]dashv2alpha1.DashboardElement, tab *dashv2alpha1.DashboardTabsLayoutTabKind, startY int64) ([]interface{}, int64, error) {
|
|
|
|
|
panels := make([]interface{}, 0)
|
|
|
|
|
currentY := startY
|
|
|
|
|
|
|
|
|
@@ -487,7 +479,7 @@ func processTabItem(elements map[string]dashv2alpha1.DashboardElement, tab *dash
|
|
|
|
|
// Handle nested layouts inside the tab
|
|
|
|
|
if tab.Spec.Layout.RowsLayoutKind != nil {
|
|
|
|
|
// Nested RowsLayout inside tab
|
|
|
|
|
nestedPanels, err := convertNestedLayoutToPanels(elements, tab.Spec.Layout.RowsLayoutKind, nil, dsIndex, currentY)
|
|
|
|
|
nestedPanels, err := convertNestedLayoutToPanels(elements, tab.Spec.Layout.RowsLayoutKind, nil, currentY)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, 0, err
|
|
|
|
|
}
|
|
|
|
@@ -495,7 +487,7 @@ func processTabItem(elements map[string]dashv2alpha1.DashboardElement, tab *dash
|
|
|
|
|
currentY = getMaxYFromPanels(nestedPanels, currentY)
|
|
|
|
|
} else if tab.Spec.Layout.TabsLayoutKind != nil {
|
|
|
|
|
// Nested TabsLayout inside tab
|
|
|
|
|
nestedPanels, err := convertNestedLayoutToPanels(elements, nil, tab.Spec.Layout.TabsLayoutKind, dsIndex, currentY)
|
|
|
|
|
nestedPanels, err := convertNestedLayoutToPanels(elements, nil, tab.Spec.Layout.TabsLayoutKind, currentY)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, 0, err
|
|
|
|
|
}
|
|
|
|
@@ -512,7 +504,7 @@ func processTabItem(elements map[string]dashv2alpha1.DashboardElement, tab *dash
|
|
|
|
|
adjustedItem := item
|
|
|
|
|
adjustedItem.Spec.Y = item.Spec.Y + currentY
|
|
|
|
|
|
|
|
|
|
panel, err := convertPanelFromElement(&element, &adjustedItem, dsIndex)
|
|
|
|
|
panel, err := convertPanelFromElement(&element, &adjustedItem)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, 0, fmt.Errorf("failed to convert panel %s: %w", item.Spec.Element.Name, err)
|
|
|
|
|
}
|
|
|
|
@@ -525,7 +517,7 @@ func processTabItem(elements map[string]dashv2alpha1.DashboardElement, tab *dash
|
|
|
|
|
}
|
|
|
|
|
} else if tab.Spec.Layout.AutoGridLayoutKind != nil {
|
|
|
|
|
// AutoGridLayout inside tab - convert with Y offset
|
|
|
|
|
autoGridPanels, err := convertAutoGridLayoutToPanelsWithOffset(elements, tab.Spec.Layout.AutoGridLayoutKind, dsIndex, currentY)
|
|
|
|
|
autoGridPanels, err := convertAutoGridLayoutToPanelsWithOffset(elements, tab.Spec.Layout.AutoGridLayoutKind, currentY)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, 0, err
|
|
|
|
|
}
|
|
|
|
@@ -540,7 +532,7 @@ func processTabItem(elements map[string]dashv2alpha1.DashboardElement, tab *dash
|
|
|
|
|
// Panels are positioned with absolute Y coordinates (baseY + relative Y).
|
|
|
|
|
// This matches V1 behavior where collapsed row panels store their children
|
|
|
|
|
// with Y positions as if the row were expanded at that location.
|
|
|
|
|
func extractCollapsedPanelsWithAbsoluteY(elements map[string]dashv2alpha1.DashboardElement, layout *dashv2alpha1.DashboardGridLayoutKindOrAutoGridLayoutKindOrTabsLayoutKindOrRowsLayoutKind, dsIndex *schemaversion.DatasourceIndex, baseY int64) ([]interface{}, error) {
|
|
|
|
|
func extractCollapsedPanelsWithAbsoluteY(elements map[string]dashv2alpha1.DashboardElement, layout *dashv2alpha1.DashboardGridLayoutKindOrAutoGridLayoutKindOrTabsLayoutKindOrRowsLayoutKind, baseY int64) ([]interface{}, error) {
|
|
|
|
|
panels := make([]interface{}, 0)
|
|
|
|
|
|
|
|
|
|
if layout.GridLayoutKind != nil {
|
|
|
|
@@ -552,7 +544,7 @@ func extractCollapsedPanelsWithAbsoluteY(elements map[string]dashv2alpha1.Dashbo
|
|
|
|
|
// Create a copy with adjusted Y position
|
|
|
|
|
adjustedItem := item
|
|
|
|
|
adjustedItem.Spec.Y = item.Spec.Y + baseY
|
|
|
|
|
panel, err := convertPanelFromElement(&element, &adjustedItem, dsIndex)
|
|
|
|
|
panel, err := convertPanelFromElement(&element, &adjustedItem)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("failed to convert panel %s: %w", item.Spec.Element.Name, err)
|
|
|
|
|
}
|
|
|
|
@@ -561,7 +553,7 @@ func extractCollapsedPanelsWithAbsoluteY(elements map[string]dashv2alpha1.Dashbo
|
|
|
|
|
}
|
|
|
|
|
// Handle AutoGridLayout for collapsed rows with Y offset
|
|
|
|
|
if layout.AutoGridLayoutKind != nil {
|
|
|
|
|
autoGridPanels, err := convertAutoGridLayoutToPanelsWithOffset(elements, layout.AutoGridLayoutKind, dsIndex, baseY)
|
|
|
|
|
autoGridPanels, err := convertAutoGridLayoutToPanelsWithOffset(elements, layout.AutoGridLayoutKind, baseY)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
@@ -571,7 +563,7 @@ func extractCollapsedPanelsWithAbsoluteY(elements map[string]dashv2alpha1.Dashbo
|
|
|
|
|
if layout.RowsLayoutKind != nil {
|
|
|
|
|
currentY := baseY
|
|
|
|
|
for _, row := range layout.RowsLayoutKind.Spec.Rows {
|
|
|
|
|
nestedPanels, err := extractCollapsedPanelsWithAbsoluteY(elements, &row.Spec.Layout, dsIndex, currentY)
|
|
|
|
|
nestedPanels, err := extractCollapsedPanelsWithAbsoluteY(elements, &row.Spec.Layout, currentY)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
@@ -582,7 +574,7 @@ func extractCollapsedPanelsWithAbsoluteY(elements map[string]dashv2alpha1.Dashbo
|
|
|
|
|
if layout.TabsLayoutKind != nil {
|
|
|
|
|
currentY := baseY
|
|
|
|
|
for _, tab := range layout.TabsLayoutKind.Spec.Tabs {
|
|
|
|
|
nestedPanels, err := extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements, &tab.Spec.Layout, dsIndex, currentY)
|
|
|
|
|
nestedPanels, err := extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements, &tab.Spec.Layout, currentY)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
@@ -596,7 +588,7 @@ func extractCollapsedPanelsWithAbsoluteY(elements map[string]dashv2alpha1.Dashbo
|
|
|
|
|
|
|
|
|
|
// extractCollapsedPanelsFromTabLayoutWithAbsoluteY extracts panels from a tab layout with absolute Y.
|
|
|
|
|
// Similar to extractCollapsedPanelsWithAbsoluteY but handles the tab-specific layout type.
|
|
|
|
|
func extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements map[string]dashv2alpha1.DashboardElement, layout *dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind, dsIndex *schemaversion.DatasourceIndex, baseY int64) ([]interface{}, error) {
|
|
|
|
|
func extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements map[string]dashv2alpha1.DashboardElement, layout *dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind, baseY int64) ([]interface{}, error) {
|
|
|
|
|
panels := make([]interface{}, 0)
|
|
|
|
|
|
|
|
|
|
if layout.GridLayoutKind != nil {
|
|
|
|
@@ -607,7 +599,7 @@ func extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements map[string]dashv2
|
|
|
|
|
}
|
|
|
|
|
adjustedItem := item
|
|
|
|
|
adjustedItem.Spec.Y = item.Spec.Y + baseY
|
|
|
|
|
panel, err := convertPanelFromElement(&element, &adjustedItem, dsIndex)
|
|
|
|
|
panel, err := convertPanelFromElement(&element, &adjustedItem)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("failed to convert panel %s: %w", item.Spec.Element.Name, err)
|
|
|
|
|
}
|
|
|
|
@@ -615,7 +607,7 @@ func extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements map[string]dashv2
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if layout.AutoGridLayoutKind != nil {
|
|
|
|
|
autoGridPanels, err := convertAutoGridLayoutToPanelsWithOffset(elements, layout.AutoGridLayoutKind, dsIndex, baseY)
|
|
|
|
|
autoGridPanels, err := convertAutoGridLayoutToPanelsWithOffset(elements, layout.AutoGridLayoutKind, baseY)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
@@ -624,7 +616,7 @@ func extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements map[string]dashv2
|
|
|
|
|
if layout.RowsLayoutKind != nil {
|
|
|
|
|
currentY := baseY
|
|
|
|
|
for _, row := range layout.RowsLayoutKind.Spec.Rows {
|
|
|
|
|
nestedPanels, err := extractCollapsedPanelsWithAbsoluteY(elements, &row.Spec.Layout, dsIndex, currentY)
|
|
|
|
|
nestedPanels, err := extractCollapsedPanelsWithAbsoluteY(elements, &row.Spec.Layout, currentY)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
@@ -635,7 +627,7 @@ func extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements map[string]dashv2
|
|
|
|
|
if layout.TabsLayoutKind != nil {
|
|
|
|
|
currentY := baseY
|
|
|
|
|
for _, tab := range layout.TabsLayoutKind.Spec.Tabs {
|
|
|
|
|
nestedPanels, err := extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements, &tab.Spec.Layout, dsIndex, currentY)
|
|
|
|
|
nestedPanels, err := extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements, &tab.Spec.Layout, currentY)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
@@ -679,7 +671,7 @@ func getLayoutHeightFromTab(layout *dashv2alpha1.DashboardGridLayoutKindOrRowsLa
|
|
|
|
|
// - Explicit row: Add (currentY - 1) to relative Y for absolute positioning
|
|
|
|
|
//
|
|
|
|
|
// Returns the panels and the new Y position for the next row.
|
|
|
|
|
func extractExpandedPanels(elements map[string]dashv2alpha1.DashboardElement, layout *dashv2alpha1.DashboardGridLayoutKindOrAutoGridLayoutKindOrTabsLayoutKindOrRowsLayoutKind, dsIndex *schemaversion.DatasourceIndex, currentY int64, isHiddenHeader bool, startY int64) ([]interface{}, int64, error) {
|
|
|
|
|
func extractExpandedPanels(elements map[string]dashv2alpha1.DashboardElement, layout *dashv2alpha1.DashboardGridLayoutKindOrAutoGridLayoutKindOrTabsLayoutKindOrRowsLayoutKind, currentY int64, isHiddenHeader bool, startY int64) ([]interface{}, int64, error) {
|
|
|
|
|
panels := make([]interface{}, 0)
|
|
|
|
|
// For hidden headers, don't track Y changes (matches original behavior)
|
|
|
|
|
maxY := startY
|
|
|
|
@@ -700,7 +692,7 @@ func extractExpandedPanels(elements map[string]dashv2alpha1.DashboardElement, la
|
|
|
|
|
}
|
|
|
|
|
// For hidden headers: don't adjust Y, keep item.Spec.Y as-is
|
|
|
|
|
|
|
|
|
|
panel, err := convertPanelFromElement(&element, &adjustedItem, dsIndex)
|
|
|
|
|
panel, err := convertPanelFromElement(&element, &adjustedItem)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, 0, fmt.Errorf("failed to convert panel %s: %w", item.Spec.Element.Name, err)
|
|
|
|
|
}
|
|
|
|
@@ -725,7 +717,7 @@ func extractExpandedPanels(elements map[string]dashv2alpha1.DashboardElement, la
|
|
|
|
|
yOffset = currentY - 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
autoGridPanels, err := convertAutoGridLayoutToPanelsWithOffset(elements, layout.AutoGridLayoutKind, dsIndex, yOffset)
|
|
|
|
|
autoGridPanels, err := convertAutoGridLayoutToPanelsWithOffset(elements, layout.AutoGridLayoutKind, yOffset)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, 0, err
|
|
|
|
|
}
|
|
|
|
@@ -788,7 +780,7 @@ func getLayoutHeight(layout *dashv2alpha1.DashboardGridLayoutKindOrAutoGridLayou
|
|
|
|
|
// convertAutoGridLayoutToPanelsWithOffset converts AutoGridLayout with a Y offset.
|
|
|
|
|
// Same as convertAutoGridLayoutToPanels but starts at yOffset instead of 0.
|
|
|
|
|
// Used when AutoGridLayout appears inside rows or tabs.
|
|
|
|
|
func convertAutoGridLayoutToPanelsWithOffset(elements map[string]dashv2alpha1.DashboardElement, autoGridLayout *dashv2alpha1.DashboardAutoGridLayoutKind, dsIndex *schemaversion.DatasourceIndex, yOffset int64) ([]interface{}, error) {
|
|
|
|
|
func convertAutoGridLayoutToPanelsWithOffset(elements map[string]dashv2alpha1.DashboardElement, autoGridLayout *dashv2alpha1.DashboardAutoGridLayoutKind, yOffset int64) ([]interface{}, error) {
|
|
|
|
|
panels := make([]interface{}, 0, len(autoGridLayout.Spec.Items))
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
@@ -850,7 +842,7 @@ func convertAutoGridLayoutToPanelsWithOffset(elements map[string]dashv2alpha1.Da
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
panel, err := convertPanelFromElement(&element, &gridItem, dsIndex)
|
|
|
|
|
panel, err := convertPanelFromElement(&element, &gridItem)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("failed to convert panel %s: %w", item.Spec.Element.Name, err)
|
|
|
|
|
}
|
|
|
|
@@ -876,7 +868,7 @@ func convertAutoGridLayoutToPanelsWithOffset(elements map[string]dashv2alpha1.Da
|
|
|
|
|
//
|
|
|
|
|
// Width: 24 / maxColumnCount (default 3 columns = 8 units wide)
|
|
|
|
|
// Height: Predefined grid units per mode (see pixelsToGridUnits for custom)
|
|
|
|
|
func convertAutoGridLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, autoGridLayout *dashv2alpha1.DashboardAutoGridLayoutKind, dsIndex *schemaversion.DatasourceIndex) ([]interface{}, error) {
|
|
|
|
|
func convertAutoGridLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, autoGridLayout *dashv2alpha1.DashboardAutoGridLayoutKind) ([]interface{}, error) {
|
|
|
|
|
panels := make([]interface{}, 0, len(autoGridLayout.Spec.Items))
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
@@ -963,7 +955,7 @@ func convertAutoGridLayoutToPanels(elements map[string]dashv2alpha1.DashboardEle
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
panel, err := convertPanelFromElement(&element, &gridItem, dsIndex)
|
|
|
|
|
panel, err := convertPanelFromElement(&element, &gridItem)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("failed to convert panel %s: %w", item.Spec.Element.Name, err)
|
|
|
|
|
}
|
|
|
|
@@ -984,11 +976,11 @@ func convertAutoGridLayoutToPanels(elements map[string]dashv2alpha1.DashboardEle
|
|
|
|
|
// V1 has no native tab concept, so tabs are converted to expanded row panels.
|
|
|
|
|
// Each tab becomes a row panel (collapsed=false, panels=[]) with its content
|
|
|
|
|
// flattened to the top level. Tab order is preserved in the output.
|
|
|
|
|
func convertTabsLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, tabsLayout *dashv2alpha1.DashboardTabsLayoutKind, dsIndex *schemaversion.DatasourceIndex) ([]interface{}, error) {
|
|
|
|
|
return convertNestedLayoutToPanels(elements, nil, tabsLayout, dsIndex, 0)
|
|
|
|
|
func convertTabsLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, tabsLayout *dashv2alpha1.DashboardTabsLayoutKind) ([]interface{}, error) {
|
|
|
|
|
return convertNestedLayoutToPanels(elements, nil, tabsLayout, 0)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func convertPanelFromElement(element *dashv2alpha1.DashboardElement, layoutItem *dashv2alpha1.DashboardGridLayoutItemKind, dsIndex *schemaversion.DatasourceIndex) (map[string]interface{}, error) {
|
|
|
|
|
func convertPanelFromElement(element *dashv2alpha1.DashboardElement, layoutItem *dashv2alpha1.DashboardGridLayoutItemKind) (map[string]interface{}, error) {
|
|
|
|
|
panel := make(map[string]interface{})
|
|
|
|
|
|
|
|
|
|
// Set grid position
|
|
|
|
@@ -1017,7 +1009,7 @@ func convertPanelFromElement(element *dashv2alpha1.DashboardElement, layoutItem
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if element.PanelKind != nil {
|
|
|
|
|
return convertPanelKindToV1(element.PanelKind, panel, dsIndex)
|
|
|
|
|
return convertPanelKindToV1(element.PanelKind, panel)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if element.LibraryPanelKind != nil {
|
|
|
|
@@ -1027,7 +1019,7 @@ func convertPanelFromElement(element *dashv2alpha1.DashboardElement, layoutItem
|
|
|
|
|
return nil, fmt.Errorf("element has neither PanelKind nor LibraryPanelKind")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func convertPanelKindToV1(panelKind *dashv2alpha1.DashboardPanelKind, panel map[string]interface{}, dsIndex *schemaversion.DatasourceIndex) (map[string]interface{}, error) {
|
|
|
|
|
func convertPanelKindToV1(panelKind *dashv2alpha1.DashboardPanelKind, panel map[string]interface{}) (map[string]interface{}, error) {
|
|
|
|
|
spec := panelKind.Spec
|
|
|
|
|
|
|
|
|
|
panel["id"] = int(spec.Id)
|
|
|
|
@@ -1069,14 +1061,14 @@ func convertPanelKindToV1(panelKind *dashv2alpha1.DashboardPanelKind, panel map[
|
|
|
|
|
// Convert queries (targets)
|
|
|
|
|
targets := make([]map[string]interface{}, 0, len(spec.Data.Spec.Queries))
|
|
|
|
|
for _, query := range spec.Data.Spec.Queries {
|
|
|
|
|
target := convertPanelQueryToV1(&query, dsIndex)
|
|
|
|
|
target := convertPanelQueryToV1(&query)
|
|
|
|
|
targets = append(targets, target)
|
|
|
|
|
}
|
|
|
|
|
panel["targets"] = targets
|
|
|
|
|
|
|
|
|
|
// Detect mixed datasource - set panel.datasource to "mixed" if queries use different datasources
|
|
|
|
|
// This matches the frontend behavior in getPanelDataSource (layoutSerializers/utils.ts)
|
|
|
|
|
if mixedDS := detectMixedDatasource(spec.Data.Spec.Queries, dsIndex); mixedDS != nil {
|
|
|
|
|
if mixedDS := detectMixedDatasource(spec.Data.Spec.Queries); mixedDS != nil {
|
|
|
|
|
panel["datasource"] = mixedDS
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -1125,7 +1117,7 @@ func convertPanelKindToV1(panelKind *dashv2alpha1.DashboardPanelKind, panel map[
|
|
|
|
|
return panel, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func convertPanelQueryToV1(query *dashv2alpha1.DashboardPanelQueryKind, dsIndex *schemaversion.DatasourceIndex) map[string]interface{} {
|
|
|
|
|
func convertPanelQueryToV1(query *dashv2alpha1.DashboardPanelQueryKind) map[string]interface{} {
|
|
|
|
|
target := make(map[string]interface{})
|
|
|
|
|
|
|
|
|
|
// Copy query spec (excluding refId, hide, datasource which are handled separately)
|
|
|
|
@@ -1150,7 +1142,7 @@ func convertPanelQueryToV1(query *dashv2alpha1.DashboardPanelQueryKind, dsIndex
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Resolve datasource based on V2 input (reuse shared function)
|
|
|
|
|
datasource := getDataSourceForQuery(query.Spec.Datasource, query.Spec.Query.Kind, nil)
|
|
|
|
|
datasource := getDataSourceForQuery(query.Spec.Datasource, query.Spec.Query.Kind)
|
|
|
|
|
if datasource != nil {
|
|
|
|
|
target["datasource"] = datasource
|
|
|
|
|
}
|
|
|
|
@@ -1164,7 +1156,7 @@ func convertPanelQueryToV1(query *dashv2alpha1.DashboardPanelQueryKind, dsIndex
|
|
|
|
|
// - Else if queryKind (type) is non-empty → return {type} only
|
|
|
|
|
// - Else → return nil (no datasource)
|
|
|
|
|
// Used for variables and annotations. Panel queries use convertPanelQueryToV1Target.
|
|
|
|
|
func getDataSourceForQuery(explicitDS *dashv2alpha1.DashboardDataSourceRef, queryKind string, _ *schemaversion.DatasourceIndex) map[string]interface{} {
|
|
|
|
|
func getDataSourceForQuery(explicitDS *dashv2alpha1.DashboardDataSourceRef, queryKind string) map[string]interface{} {
|
|
|
|
|
// Case 1: Explicit datasource with UID provided
|
|
|
|
|
if explicitDS != nil && explicitDS.Uid != nil && *explicitDS.Uid != "" {
|
|
|
|
|
datasource := map[string]interface{}{
|
|
|
|
@@ -1195,7 +1187,7 @@ func getDataSourceForQuery(explicitDS *dashv2alpha1.DashboardDataSourceRef, quer
|
|
|
|
|
// Compares based on V2 input without runtime resolution:
|
|
|
|
|
// - If query has explicit datasource.uid → use that UID and type
|
|
|
|
|
// - Else → use query.Kind as type (empty UID)
|
|
|
|
|
func detectMixedDatasource(queries []dashv2alpha1.DashboardPanelQueryKind, _ *schemaversion.DatasourceIndex) map[string]interface{} {
|
|
|
|
|
func detectMixedDatasource(queries []dashv2alpha1.DashboardPanelQueryKind) map[string]interface{} {
|
|
|
|
|
if len(queries) == 0 {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
@@ -1254,7 +1246,7 @@ func convertLibraryPanelKindToV1(libPanelKind *dashv2alpha1.DashboardLibraryPane
|
|
|
|
|
return panel, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func convertVariablesToV1(variables []dashv2alpha1.DashboardVariableKind, dsIndex *schemaversion.DatasourceIndex) []map[string]interface{} {
|
|
|
|
|
func convertVariablesToV1(variables []dashv2alpha1.DashboardVariableKind) []map[string]interface{} {
|
|
|
|
|
result := make([]map[string]interface{}, 0, len(variables))
|
|
|
|
|
|
|
|
|
|
for _, variable := range variables {
|
|
|
|
@@ -1262,7 +1254,7 @@ func convertVariablesToV1(variables []dashv2alpha1.DashboardVariableKind, dsInde
|
|
|
|
|
var err error
|
|
|
|
|
|
|
|
|
|
if variable.QueryVariableKind != nil {
|
|
|
|
|
varMap, err = convertQueryVariableToV1(variable.QueryVariableKind, dsIndex)
|
|
|
|
|
varMap, err = convertQueryVariableToV1(variable.QueryVariableKind)
|
|
|
|
|
} else if variable.DatasourceVariableKind != nil {
|
|
|
|
|
varMap, err = convertDatasourceVariableToV1(variable.DatasourceVariableKind)
|
|
|
|
|
} else if variable.CustomVariableKind != nil {
|
|
|
|
@@ -1274,9 +1266,9 @@ func convertVariablesToV1(variables []dashv2alpha1.DashboardVariableKind, dsInde
|
|
|
|
|
} else if variable.TextVariableKind != nil {
|
|
|
|
|
varMap, err = convertTextVariableToV1(variable.TextVariableKind)
|
|
|
|
|
} else if variable.GroupByVariableKind != nil {
|
|
|
|
|
varMap, err = convertGroupByVariableToV1(variable.GroupByVariableKind, dsIndex)
|
|
|
|
|
varMap, err = convertGroupByVariableToV1(variable.GroupByVariableKind)
|
|
|
|
|
} else if variable.AdhocVariableKind != nil {
|
|
|
|
|
varMap, err = convertAdhocVariableToV1(variable.AdhocVariableKind, dsIndex)
|
|
|
|
|
varMap, err = convertAdhocVariableToV1(variable.AdhocVariableKind)
|
|
|
|
|
} else if variable.SwitchVariableKind != nil {
|
|
|
|
|
varMap, err = convertSwitchVariableToV1(variable.SwitchVariableKind)
|
|
|
|
|
}
|
|
|
|
@@ -1289,7 +1281,7 @@ func convertVariablesToV1(variables []dashv2alpha1.DashboardVariableKind, dsInde
|
|
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func convertQueryVariableToV1(variable *dashv2alpha1.DashboardQueryVariableKind, dsIndex *schemaversion.DatasourceIndex) (map[string]interface{}, error) {
|
|
|
|
|
func convertQueryVariableToV1(variable *dashv2alpha1.DashboardQueryVariableKind) (map[string]interface{}, error) {
|
|
|
|
|
spec := variable.Spec
|
|
|
|
|
varMap := map[string]interface{}{
|
|
|
|
|
"name": spec.Name,
|
|
|
|
@@ -1336,7 +1328,7 @@ func convertQueryVariableToV1(variable *dashv2alpha1.DashboardQueryVariableKind,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Resolve datasource - use explicit datasource or resolve from query kind (datasource type)/default
|
|
|
|
|
datasource := getDataSourceForQuery(spec.Datasource, spec.Query.Kind, dsIndex)
|
|
|
|
|
datasource := getDataSourceForQuery(spec.Datasource, spec.Query.Kind)
|
|
|
|
|
if datasource != nil {
|
|
|
|
|
varMap["datasource"] = datasource
|
|
|
|
|
}
|
|
|
|
@@ -1486,7 +1478,7 @@ func convertTextVariableToV1(variable *dashv2alpha1.DashboardTextVariableKind) (
|
|
|
|
|
return varMap, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func convertGroupByVariableToV1(variable *dashv2alpha1.DashboardGroupByVariableKind, dsIndex *schemaversion.DatasourceIndex) (map[string]interface{}, error) {
|
|
|
|
|
func convertGroupByVariableToV1(variable *dashv2alpha1.DashboardGroupByVariableKind) (map[string]interface{}, error) {
|
|
|
|
|
spec := variable.Spec
|
|
|
|
|
varMap := map[string]interface{}{
|
|
|
|
|
"name": spec.Name,
|
|
|
|
@@ -1509,7 +1501,7 @@ func convertGroupByVariableToV1(variable *dashv2alpha1.DashboardGroupByVariableK
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Resolve datasource - GroupBy variables don't have a query kind, so use empty string (will fall back to default)
|
|
|
|
|
datasource := getDataSourceForQuery(spec.Datasource, "", dsIndex)
|
|
|
|
|
datasource := getDataSourceForQuery(spec.Datasource, "")
|
|
|
|
|
if datasource != nil {
|
|
|
|
|
varMap["datasource"] = datasource
|
|
|
|
|
}
|
|
|
|
@@ -1517,7 +1509,7 @@ func convertGroupByVariableToV1(variable *dashv2alpha1.DashboardGroupByVariableK
|
|
|
|
|
return varMap, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func convertAdhocVariableToV1(variable *dashv2alpha1.DashboardAdhocVariableKind, dsIndex *schemaversion.DatasourceIndex) (map[string]interface{}, error) {
|
|
|
|
|
func convertAdhocVariableToV1(variable *dashv2alpha1.DashboardAdhocVariableKind) (map[string]interface{}, error) {
|
|
|
|
|
spec := variable.Spec
|
|
|
|
|
varMap := map[string]interface{}{
|
|
|
|
|
"name": spec.Name,
|
|
|
|
@@ -1536,7 +1528,7 @@ func convertAdhocVariableToV1(variable *dashv2alpha1.DashboardAdhocVariableKind,
|
|
|
|
|
varMap["allowCustomValue"] = spec.AllowCustomValue
|
|
|
|
|
|
|
|
|
|
// Resolve datasource - Adhoc variables don't have a query kind, so use empty string (will fall back to default)
|
|
|
|
|
datasource := getDataSourceForQuery(spec.Datasource, "", dsIndex)
|
|
|
|
|
datasource := getDataSourceForQuery(spec.Datasource, "")
|
|
|
|
|
if datasource != nil {
|
|
|
|
|
varMap["datasource"] = datasource
|
|
|
|
|
}
|
|
|
|
@@ -1663,7 +1655,7 @@ func convertSwitchVariableToV1(variable *dashv2alpha1.DashboardSwitchVariableKin
|
|
|
|
|
return varMap, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func convertAnnotationsToV1(annotations []dashv2alpha1.DashboardAnnotationQueryKind, dsIndex *schemaversion.DatasourceIndex) []map[string]interface{} {
|
|
|
|
|
func convertAnnotationsToV1(annotations []dashv2alpha1.DashboardAnnotationQueryKind) []map[string]interface{} {
|
|
|
|
|
result := make([]map[string]interface{}, 0, len(annotations))
|
|
|
|
|
|
|
|
|
|
for _, annotation := range annotations {
|
|
|
|
@@ -1686,7 +1678,7 @@ func convertAnnotationsToV1(annotations []dashv2alpha1.DashboardAnnotationQueryK
|
|
|
|
|
if annotation.Spec.Query != nil {
|
|
|
|
|
queryKind = annotation.Spec.Query.Kind
|
|
|
|
|
}
|
|
|
|
|
datasource := getDataSourceForQuery(annotation.Spec.Datasource, queryKind, dsIndex)
|
|
|
|
|
datasource := getDataSourceForQuery(annotation.Spec.Datasource, queryKind)
|
|
|
|
|
if datasource != nil {
|
|
|
|
|
annotationMap["datasource"] = datasource
|
|
|
|
|
}
|
|
|
|
|