Dashboard Schema V2: Support panel actions (#110842)
* support panel actions * refactor * add test; move action transformer to utils * refactor so v2 headers and queryParams are just a simple record * update open api * update actions to be same shape accross all dashboard schemas and add validation on the backend * cleanup * update snapshot * add tests to validation
This commit is contained in:
@@ -221,6 +221,9 @@ FieldConfig: {
|
||||
// The behavior when clicking on a result
|
||||
links?: [...]
|
||||
|
||||
// Define interactive HTTP requests that can be triggered from data visualizations.
|
||||
actions?: [...Action]
|
||||
|
||||
// Alternative to empty string
|
||||
noValue?: string
|
||||
|
||||
@@ -364,6 +367,47 @@ FieldColor: {
|
||||
// Dashboard Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource)
|
||||
DashboardLinkType: "link" | "dashboards"
|
||||
|
||||
ActionType: "fetch" | "infinity"
|
||||
|
||||
FetchOptions: {
|
||||
method: HttpRequestMethod
|
||||
url: string
|
||||
body?: string
|
||||
// These are 2D arrays of strings, each representing a key-value pair
|
||||
// We are defining them this way because we can't generate a go struct that
|
||||
// that would have exactly two strings in each sub-array
|
||||
queryParams?: [...[...string]]
|
||||
headers?: [...[...string]]
|
||||
}
|
||||
|
||||
InfinityOptions: FetchOptions & {
|
||||
datasourceUid: string
|
||||
}
|
||||
|
||||
HttpRequestMethod: "GET" | "PUT" | "POST" | "DELETE" | "PATCH"
|
||||
|
||||
// Action variable type
|
||||
ActionVariableType: "string"
|
||||
|
||||
ActionVariable: {
|
||||
key: string
|
||||
name: string
|
||||
type: ActionVariableType
|
||||
}
|
||||
|
||||
Action: {
|
||||
type: ActionType
|
||||
title: string
|
||||
fetch?: FetchOptions
|
||||
infinity?: InfinityOptions
|
||||
confirmation?: string
|
||||
oneClick?: bool
|
||||
variables?: [...ActionVariable]
|
||||
style?: {
|
||||
backgroundColor?: string
|
||||
}
|
||||
}
|
||||
|
||||
// --- Common types ---
|
||||
Kind: {
|
||||
kind: string
|
||||
|
||||
@@ -219,6 +219,9 @@ FieldConfig: {
|
||||
// The behavior when clicking on a result
|
||||
links?: [...]
|
||||
|
||||
// Define interactive HTTP requests that can be triggered from data visualizations.
|
||||
actions?: [...Action]
|
||||
|
||||
// Alternative to empty string
|
||||
noValue?: string
|
||||
|
||||
@@ -362,6 +365,48 @@ FieldColor: {
|
||||
// Dashboard Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource)
|
||||
DashboardLinkType: "link" | "dashboards"
|
||||
|
||||
ActionType: "fetch" | "infinity"
|
||||
|
||||
FetchOptions: {
|
||||
method: HttpRequestMethod
|
||||
url: string
|
||||
body?: string
|
||||
// These are 2D arrays of strings, each representing a key-value pair
|
||||
// We are defining them this way because we can't generate a go struct that
|
||||
// that would have exactly two strings in each sub-array
|
||||
queryParams?: [...[...string]]
|
||||
headers?: [...[...string]]
|
||||
}
|
||||
|
||||
InfinityOptions: FetchOptions & {
|
||||
datasourceUid: string
|
||||
}
|
||||
|
||||
HttpRequestMethod: "GET" | "PUT" | "POST" | "DELETE" | "PATCH"
|
||||
|
||||
// Action variable type
|
||||
ActionVariableType: "string"
|
||||
|
||||
ActionVariable: {
|
||||
key: string
|
||||
name: string
|
||||
type: ActionVariableType
|
||||
}
|
||||
|
||||
Action: {
|
||||
type: ActionType
|
||||
title: string
|
||||
fetch?: FetchOptions
|
||||
infinity?: InfinityOptions
|
||||
confirmation?: string
|
||||
oneClick?: bool
|
||||
variables?: [...ActionVariable]
|
||||
style?: {
|
||||
backgroundColor?: string
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --- Common types ---
|
||||
Kind: {
|
||||
kind: string
|
||||
|
||||
@@ -302,6 +302,59 @@ lineage: schemas: [{
|
||||
// - "inControlsMenu" renders the link in bottom part of the dashboard controls dropdown menu
|
||||
#DashboardLinkPlacement: "inControlsMenu" @cuetsy(kind="type")
|
||||
|
||||
// Dashboard action type
|
||||
#ActionType: "fetch" | "infinity" @cuetsy(kind="type")
|
||||
|
||||
// Fetch options
|
||||
#FetchOptions: {
|
||||
method: #HttpRequestMethod
|
||||
url: string
|
||||
body?: string
|
||||
// These are 2D arrays of strings, each representing a key-value pair
|
||||
// We are defining this way because we can't generate a go struct that
|
||||
// that would have exactly two strings in each sub-array
|
||||
queryParams?: [...[...string]]
|
||||
headers?: [...[...string]]
|
||||
} @cuetsy(kind="interface")
|
||||
|
||||
// Infinity options
|
||||
#InfinityOptions: {
|
||||
method: #HttpRequestMethod
|
||||
url: string
|
||||
body?: string
|
||||
// These are 2D arrays of strings, each representing a key-value pair
|
||||
// We are defining them this way because we can't generate a go struct that
|
||||
// that would have exactly two strings in each sub-array
|
||||
queryParams?: [...[...string]]
|
||||
headers?: [...[...string]]
|
||||
datasourceUid: string
|
||||
} @cuetsy(kind="interface")
|
||||
|
||||
#HttpRequestMethod: "GET" | "PUT" | "POST" | "DELETE" | "PATCH" @cuetsy(kind="type")
|
||||
|
||||
// Action variable type
|
||||
#ActionVariableType: "string" @cuetsy(kind="type")
|
||||
|
||||
#ActionVariable: {
|
||||
key: string
|
||||
name: string
|
||||
type: #ActionVariableType
|
||||
} @cuetsy(kind="interface")
|
||||
|
||||
// Dashboard action
|
||||
#Action: {
|
||||
type: #ActionType
|
||||
title: string
|
||||
fetch?: #FetchOptions
|
||||
infinity?: #InfinityOptions
|
||||
confirmation?: string
|
||||
oneClick?: bool
|
||||
variables?: [...#ActionVariable]
|
||||
style?: {
|
||||
backgroundColor?: string
|
||||
}
|
||||
} @cuetsy(kind="interface")
|
||||
|
||||
// Dashboard variable type
|
||||
// `query`: Query-generated list of values such as metric names, server names, sensor IDs, data centers, and so on.
|
||||
// `adhoc`: Key/value filters that are automatically added to all metric queries for a data source (Prometheus, Loki, InfluxDB, and Elasticsearch only).
|
||||
@@ -731,6 +784,9 @@ lineage: schemas: [{
|
||||
// The behavior when clicking on a result
|
||||
links?: [...] @grafanamaturity(NeedsExpertReview)
|
||||
|
||||
// Define interactive HTTP requests that can be triggered from data visualizations.
|
||||
actions?: [...#Action] @grafanamaturity(NeedsExpertReview)
|
||||
|
||||
// Alternative to empty string
|
||||
noValue?: string @grafanamaturity(NeedsExpertReview)
|
||||
|
||||
|
||||
@@ -302,6 +302,59 @@ lineage: schemas: [{
|
||||
// - "inControlsMenu" renders the link in bottom part of the dashboard controls dropdown menu
|
||||
#DashboardLinkPlacement: "inControlsMenu" @cuetsy(kind="type")
|
||||
|
||||
// Dashboard action type
|
||||
#ActionType: "fetch" | "infinity" @cuetsy(kind="type")
|
||||
|
||||
// Fetch options
|
||||
#FetchOptions: {
|
||||
method: #HttpRequestMethod
|
||||
url: string
|
||||
body?: string
|
||||
// These are 2D arrays of strings, each representing a key-value pair
|
||||
// We are defining this way because we can't generate a go struct that
|
||||
// that would have exactly two strings in each sub-array
|
||||
queryParams?: [...[...string]]
|
||||
headers?: [...[...string]]
|
||||
} @cuetsy(kind="interface")
|
||||
|
||||
// Infinity options
|
||||
#InfinityOptions: {
|
||||
method: #HttpRequestMethod
|
||||
url: string
|
||||
body?: string
|
||||
// These are 2D arrays of strings, each representing a key-value pair
|
||||
// We are defining them this way because we can't generate a go struct that
|
||||
// that would have exactly two strings in each sub-array
|
||||
queryParams?: [...[...string]]
|
||||
headers?: [...[...string]]
|
||||
datasourceUid: string
|
||||
} @cuetsy(kind="interface")
|
||||
|
||||
#HttpRequestMethod: "GET" | "PUT" | "POST" | "DELETE" | "PATCH" @cuetsy(kind="type")
|
||||
|
||||
// Action variable type
|
||||
#ActionVariableType: "string" @cuetsy(kind="type")
|
||||
|
||||
#ActionVariable: {
|
||||
key: string
|
||||
name: string
|
||||
type: #ActionVariableType
|
||||
} @cuetsy(kind="interface")
|
||||
|
||||
// Dashboard action
|
||||
#Action: {
|
||||
type: #ActionType
|
||||
title: string
|
||||
fetch?: #FetchOptions
|
||||
infinity?: #InfinityOptions
|
||||
confirmation?: string
|
||||
oneClick?: bool
|
||||
variables?: [...#ActionVariable]
|
||||
style?: {
|
||||
backgroundColor?: string
|
||||
}
|
||||
} @cuetsy(kind="interface")
|
||||
|
||||
// Dashboard variable type
|
||||
// `query`: Query-generated list of values such as metric names, server names, sensor IDs, data centers, and so on.
|
||||
// `adhoc`: Key/value filters that are automatically added to all metric queries for a data source (Prometheus, Loki, InfluxDB, and Elasticsearch only).
|
||||
@@ -731,6 +784,9 @@ lineage: schemas: [{
|
||||
// The behavior when clicking on a result
|
||||
links?: [...] @grafanamaturity(NeedsExpertReview)
|
||||
|
||||
// Define interactive HTTP requests that can be triggered from data visualizations.
|
||||
actions?: [...#Action] @grafanamaturity(NeedsExpertReview)
|
||||
|
||||
// Alternative to empty string
|
||||
noValue?: string @grafanamaturity(NeedsExpertReview)
|
||||
|
||||
|
||||
@@ -225,6 +225,9 @@ FieldConfig: {
|
||||
// The behavior when clicking on a result
|
||||
links?: [...]
|
||||
|
||||
// Define interactive HTTP requests that can be triggered from data visualizations.
|
||||
actions?: [...Action]
|
||||
|
||||
// Alternative to empty string
|
||||
noValue?: string
|
||||
|
||||
@@ -368,6 +371,47 @@ FieldColor: {
|
||||
// Dashboard Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource)
|
||||
DashboardLinkType: "link" | "dashboards"
|
||||
|
||||
ActionType: "fetch" | "infinity"
|
||||
|
||||
FetchOptions: {
|
||||
method: HttpRequestMethod
|
||||
url: string
|
||||
body?: string
|
||||
// These are 2D arrays of strings, each representing a key-value pair
|
||||
// We are defining them this way because we can't generate a go struct that
|
||||
// that would have exactly two strings in each sub-array
|
||||
queryParams?: [...[...string]]
|
||||
headers?: [...[...string]]
|
||||
}
|
||||
|
||||
InfinityOptions: FetchOptions & {
|
||||
datasourceUid: string
|
||||
}
|
||||
|
||||
HttpRequestMethod: "GET" | "PUT" | "POST" | "DELETE" | "PATCH"
|
||||
|
||||
// Action variable type
|
||||
ActionVariableType: "string"
|
||||
|
||||
ActionVariable: {
|
||||
key: string
|
||||
name: string
|
||||
type: ActionVariableType
|
||||
}
|
||||
|
||||
Action: {
|
||||
type: ActionType
|
||||
title: string
|
||||
fetch?: FetchOptions
|
||||
infinity?: InfinityOptions
|
||||
confirmation?: string
|
||||
oneClick?: bool
|
||||
variables?: [...ActionVariable]
|
||||
style?: {
|
||||
backgroundColor?: string
|
||||
}
|
||||
}
|
||||
|
||||
// --- Common types ---
|
||||
Kind: {
|
||||
kind: string
|
||||
|
||||
@@ -392,6 +392,8 @@ type DashboardFieldConfig struct {
|
||||
Color *DashboardFieldColor `json:"color,omitempty"`
|
||||
// The behavior when clicking on a result
|
||||
Links []interface{} `json:"links,omitempty"`
|
||||
// Define interactive HTTP requests that can be triggered from data visualizations.
|
||||
Actions []DashboardAction `json:"actions,omitempty"`
|
||||
// Alternative to empty string
|
||||
NoValue *string `json:"noValue,omitempty"`
|
||||
// custom is specified by the FieldConfig field
|
||||
@@ -623,6 +625,95 @@ const (
|
||||
DashboardFieldColorSeriesByModeLast DashboardFieldColorSeriesByMode = "last"
|
||||
)
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type DashboardAction struct {
|
||||
Type DashboardActionType `json:"type"`
|
||||
Title string `json:"title"`
|
||||
Fetch *DashboardFetchOptions `json:"fetch,omitempty"`
|
||||
Infinity *DashboardInfinityOptions `json:"infinity,omitempty"`
|
||||
Confirmation *string `json:"confirmation,omitempty"`
|
||||
OneClick *bool `json:"oneClick,omitempty"`
|
||||
Variables []DashboardActionVariable `json:"variables,omitempty"`
|
||||
Style *DashboardV2alpha1ActionStyle `json:"style,omitempty"`
|
||||
}
|
||||
|
||||
// NewDashboardAction creates a new DashboardAction object.
|
||||
func NewDashboardAction() *DashboardAction {
|
||||
return &DashboardAction{}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type DashboardActionType string
|
||||
|
||||
const (
|
||||
DashboardActionTypeFetch DashboardActionType = "fetch"
|
||||
DashboardActionTypeInfinity DashboardActionType = "infinity"
|
||||
)
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type DashboardFetchOptions struct {
|
||||
Method DashboardHttpRequestMethod `json:"method"`
|
||||
Url string `json:"url"`
|
||||
Body *string `json:"body,omitempty"`
|
||||
// These are 2D arrays of strings, each representing a key-value pair
|
||||
// We are defining them this way because we can't generate a go struct that
|
||||
// that would have exactly two strings in each sub-array
|
||||
QueryParams [][]string `json:"queryParams,omitempty"`
|
||||
Headers [][]string `json:"headers,omitempty"`
|
||||
}
|
||||
|
||||
// NewDashboardFetchOptions creates a new DashboardFetchOptions object.
|
||||
func NewDashboardFetchOptions() *DashboardFetchOptions {
|
||||
return &DashboardFetchOptions{}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type DashboardHttpRequestMethod string
|
||||
|
||||
const (
|
||||
DashboardHttpRequestMethodGET DashboardHttpRequestMethod = "GET"
|
||||
DashboardHttpRequestMethodPUT DashboardHttpRequestMethod = "PUT"
|
||||
DashboardHttpRequestMethodPOST DashboardHttpRequestMethod = "POST"
|
||||
DashboardHttpRequestMethodDELETE DashboardHttpRequestMethod = "DELETE"
|
||||
DashboardHttpRequestMethodPATCH DashboardHttpRequestMethod = "PATCH"
|
||||
)
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type DashboardInfinityOptions struct {
|
||||
Method DashboardHttpRequestMethod `json:"method"`
|
||||
Url string `json:"url"`
|
||||
Body *string `json:"body,omitempty"`
|
||||
// These are 2D arrays of strings, each representing a key-value pair
|
||||
// We are defining them this way because we can't generate a go struct that
|
||||
// that would have exactly two strings in each sub-array
|
||||
QueryParams [][]string `json:"queryParams,omitempty"`
|
||||
DatasourceUid string `json:"datasourceUid"`
|
||||
Headers [][]string `json:"headers,omitempty"`
|
||||
}
|
||||
|
||||
// NewDashboardInfinityOptions creates a new DashboardInfinityOptions object.
|
||||
func NewDashboardInfinityOptions() *DashboardInfinityOptions {
|
||||
return &DashboardInfinityOptions{}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type DashboardActionVariable struct {
|
||||
Key string `json:"key"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
// NewDashboardActionVariable creates a new DashboardActionVariable object.
|
||||
func NewDashboardActionVariable() *DashboardActionVariable {
|
||||
return &DashboardActionVariable{
|
||||
Type: DashboardActionVariableType,
|
||||
}
|
||||
}
|
||||
|
||||
// Action variable type
|
||||
// +k8s:openapi-gen=true
|
||||
const DashboardActionVariableType = "string"
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type DashboardDynamicConfigValue struct {
|
||||
Id string `json:"id"`
|
||||
@@ -1831,6 +1922,16 @@ func NewDashboardV2alpha1SpecialValueMapOptions() *DashboardV2alpha1SpecialValue
|
||||
}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type DashboardV2alpha1ActionStyle struct {
|
||||
BackgroundColor *string `json:"backgroundColor,omitempty"`
|
||||
}
|
||||
|
||||
// NewDashboardV2alpha1ActionStyle creates a new DashboardV2alpha1ActionStyle object.
|
||||
func NewDashboardV2alpha1ActionStyle() *DashboardV2alpha1ActionStyle {
|
||||
return &DashboardV2alpha1ActionStyle{}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type DashboardRepeatOptionsDirection string
|
||||
|
||||
|
||||
@@ -23,6 +23,9 @@ func ValidateDashboardSpec(obj *Dashboard) field.ErrorList {
|
||||
}
|
||||
}
|
||||
|
||||
// Custom validation for action query params and headers
|
||||
validateAndTrimActionArrays(obj)
|
||||
|
||||
if err := cuejson.Validate(data, getCueSchema()); err != nil {
|
||||
errs := field.ErrorList{}
|
||||
|
||||
@@ -60,6 +63,61 @@ func ValidateDashboardSpec(obj *Dashboard) field.ErrorList {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validates and trims action query params and headers to exactly 2 elements each
|
||||
// This is because we couldn't generate with cue a go struct that would have exactly two strings in each sub-array
|
||||
func validateAndTrimActionArrays(obj *Dashboard) {
|
||||
for _, element := range obj.Spec.Elements {
|
||||
if element.PanelKind != nil {
|
||||
panelElement := element.PanelKind
|
||||
if panelElement.Spec.VizConfig.Spec.FieldConfig.Defaults.Actions != nil {
|
||||
processActions(panelElement.Spec.VizConfig.Spec.FieldConfig.Defaults.Actions)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to process action arrays
|
||||
func processActions(actions []DashboardAction) {
|
||||
for _, action := range actions {
|
||||
// Process FetchOptions if present
|
||||
if action.Fetch != nil {
|
||||
if action.Fetch.QueryParams != nil {
|
||||
action.Fetch.QueryParams = trimStringArrays(action.Fetch.QueryParams)
|
||||
}
|
||||
if action.Fetch.Headers != nil {
|
||||
action.Fetch.Headers = trimStringArrays(action.Fetch.Headers)
|
||||
}
|
||||
}
|
||||
|
||||
// Process InfinityOptions if present
|
||||
if action.Infinity != nil {
|
||||
if action.Infinity.QueryParams != nil {
|
||||
action.Infinity.QueryParams = trimStringArrays(action.Infinity.QueryParams)
|
||||
}
|
||||
if action.Infinity.Headers != nil {
|
||||
action.Infinity.Headers = trimStringArrays(action.Infinity.Headers)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to trim 2D string arrays to exactly 2 elements per sub-array
|
||||
func trimStringArrays(arrays [][]string) [][]string {
|
||||
if arrays == nil {
|
||||
return arrays
|
||||
}
|
||||
|
||||
result := make([][]string, len(arrays))
|
||||
for i, arr := range arrays {
|
||||
if len(arr) > 2 {
|
||||
result[i] = arr[:2]
|
||||
} else {
|
||||
result[i] = arr
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func formatErrorPath(path []string) string {
|
||||
return strings.Join(path, ".")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,495 @@
|
||||
package v2alpha1
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func TestTrimStringArrays(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input [][]string
|
||||
expected [][]string
|
||||
}{
|
||||
{
|
||||
name: "nil input",
|
||||
input: nil,
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
name: "empty input",
|
||||
input: [][]string{},
|
||||
expected: [][]string{},
|
||||
},
|
||||
{
|
||||
name: "arrays with exactly 2 elements",
|
||||
input: [][]string{{"key1", "value1"}, {"key2", "value2"}},
|
||||
expected: [][]string{{"key1", "value1"}, {"key2", "value2"}},
|
||||
},
|
||||
{
|
||||
name: "arrays with less than 2 elements",
|
||||
input: [][]string{{"key1"}, {}},
|
||||
expected: [][]string{{"key1"}, {}},
|
||||
},
|
||||
{
|
||||
name: "arrays with more than 2 elements",
|
||||
input: [][]string{{"key1", "value1", "extra1"}, {"key2", "value2", "extra2", "extra3"}},
|
||||
expected: [][]string{{"key1", "value1"}, {"key2", "value2"}},
|
||||
},
|
||||
{
|
||||
name: "mixed arrays",
|
||||
input: [][]string{{"key1"}, {"key2", "value2"}, {"key3", "value3", "extra"}},
|
||||
expected: [][]string{{"key1"}, {"key2", "value2"}, {"key3", "value3"}},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := trimStringArrays(tt.input)
|
||||
assert.Equal(t, tt.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessActions(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
actions []DashboardAction
|
||||
expected []DashboardAction
|
||||
}{
|
||||
{
|
||||
name: "empty actions",
|
||||
actions: []DashboardAction{},
|
||||
expected: []DashboardAction{},
|
||||
},
|
||||
{
|
||||
name: "action with fetch options having oversized arrays",
|
||||
actions: []DashboardAction{
|
||||
{
|
||||
Type: DashboardActionTypeFetch,
|
||||
Title: "Test Fetch",
|
||||
Fetch: &DashboardFetchOptions{
|
||||
Method: DashboardHttpRequestMethodGET,
|
||||
Url: "http://example.com",
|
||||
QueryParams: [][]string{
|
||||
{"param1", "value1", "extra1"},
|
||||
{"param2", "value2"},
|
||||
},
|
||||
Headers: [][]string{
|
||||
{"header1", "value1", "extra1", "extra2"},
|
||||
{"header2", "value2"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: []DashboardAction{
|
||||
{
|
||||
Type: DashboardActionTypeFetch,
|
||||
Title: "Test Fetch",
|
||||
Fetch: &DashboardFetchOptions{
|
||||
Method: DashboardHttpRequestMethodGET,
|
||||
Url: "http://example.com",
|
||||
QueryParams: [][]string{
|
||||
{"param1", "value1"},
|
||||
{"param2", "value2"},
|
||||
},
|
||||
Headers: [][]string{
|
||||
{"header1", "value1"},
|
||||
{"header2", "value2"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "action with infinity options having oversized arrays",
|
||||
actions: []DashboardAction{
|
||||
{
|
||||
Type: DashboardActionTypeInfinity,
|
||||
Title: "Test Infinity",
|
||||
Infinity: &DashboardInfinityOptions{
|
||||
Method: DashboardHttpRequestMethodPOST,
|
||||
Url: "http://example.com",
|
||||
DatasourceUid: "test-uid",
|
||||
QueryParams: [][]string{
|
||||
{"param1", "value1", "extra1"},
|
||||
{"param2", "value2"},
|
||||
},
|
||||
Headers: [][]string{
|
||||
{"header1", "value1", "extra1", "extra2"},
|
||||
{"header2", "value2"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: []DashboardAction{
|
||||
{
|
||||
Type: DashboardActionTypeInfinity,
|
||||
Title: "Test Infinity",
|
||||
Infinity: &DashboardInfinityOptions{
|
||||
Method: DashboardHttpRequestMethodPOST,
|
||||
Url: "http://example.com",
|
||||
DatasourceUid: "test-uid",
|
||||
QueryParams: [][]string{
|
||||
{"param1", "value1"},
|
||||
{"param2", "value2"},
|
||||
},
|
||||
Headers: [][]string{
|
||||
{"header1", "value1"},
|
||||
{"header2", "value2"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "action without fetch or infinity options",
|
||||
actions: []DashboardAction{
|
||||
{
|
||||
Type: DashboardActionTypeFetch,
|
||||
Title: "Test Action",
|
||||
},
|
||||
},
|
||||
expected: []DashboardAction{
|
||||
{
|
||||
Type: DashboardActionTypeFetch,
|
||||
Title: "Test Action",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Create a copy to avoid modifying the original
|
||||
actionsCopy := make([]DashboardAction, len(tt.actions))
|
||||
for i, action := range tt.actions {
|
||||
actionsCopy[i] = action
|
||||
// Deep copy the fetch options if they exist
|
||||
if action.Fetch != nil {
|
||||
fetchCopy := *action.Fetch
|
||||
if action.Fetch.QueryParams != nil {
|
||||
fetchCopy.QueryParams = make([][]string, len(action.Fetch.QueryParams))
|
||||
for j, param := range action.Fetch.QueryParams {
|
||||
fetchCopy.QueryParams[j] = make([]string, len(param))
|
||||
copy(fetchCopy.QueryParams[j], param)
|
||||
}
|
||||
}
|
||||
if action.Fetch.Headers != nil {
|
||||
fetchCopy.Headers = make([][]string, len(action.Fetch.Headers))
|
||||
for j, header := range action.Fetch.Headers {
|
||||
fetchCopy.Headers[j] = make([]string, len(header))
|
||||
copy(fetchCopy.Headers[j], header)
|
||||
}
|
||||
}
|
||||
actionsCopy[i].Fetch = &fetchCopy
|
||||
}
|
||||
// Deep copy the infinity options if they exist
|
||||
if action.Infinity != nil {
|
||||
infinityCopy := *action.Infinity
|
||||
if action.Infinity.QueryParams != nil {
|
||||
infinityCopy.QueryParams = make([][]string, len(action.Infinity.QueryParams))
|
||||
for j, param := range action.Infinity.QueryParams {
|
||||
infinityCopy.QueryParams[j] = make([]string, len(param))
|
||||
copy(infinityCopy.QueryParams[j], param)
|
||||
}
|
||||
}
|
||||
if action.Infinity.Headers != nil {
|
||||
infinityCopy.Headers = make([][]string, len(action.Infinity.Headers))
|
||||
for j, header := range action.Infinity.Headers {
|
||||
infinityCopy.Headers[j] = make([]string, len(header))
|
||||
copy(infinityCopy.Headers[j], header)
|
||||
}
|
||||
}
|
||||
actionsCopy[i].Infinity = &infinityCopy
|
||||
}
|
||||
}
|
||||
|
||||
processActions(actionsCopy)
|
||||
assert.Equal(t, tt.expected, actionsCopy)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateAndTrimActionArrays(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
dashboard *Dashboard
|
||||
expected *Dashboard
|
||||
}{
|
||||
{
|
||||
name: "dashboard with no elements",
|
||||
dashboard: &Dashboard{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Dashboard",
|
||||
APIVersion: "v2beta1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-dashboard",
|
||||
},
|
||||
Spec: DashboardSpec{
|
||||
Elements: map[string]DashboardElement{},
|
||||
},
|
||||
},
|
||||
expected: &Dashboard{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Dashboard",
|
||||
APIVersion: "v2beta1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-dashboard",
|
||||
},
|
||||
Spec: DashboardSpec{
|
||||
Elements: map[string]DashboardElement{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "dashboard with panel having actions with oversized arrays",
|
||||
dashboard: &Dashboard{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Dashboard",
|
||||
APIVersion: "v2beta1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-dashboard",
|
||||
},
|
||||
Spec: DashboardSpec{
|
||||
Elements: map[string]DashboardElement{
|
||||
"panel1": {
|
||||
PanelKind: &DashboardPanelKind{
|
||||
Spec: DashboardPanelSpec{
|
||||
VizConfig: DashboardVizConfigKind{
|
||||
Spec: DashboardVizConfigSpec{
|
||||
FieldConfig: DashboardFieldConfigSource{
|
||||
Defaults: DashboardFieldConfig{
|
||||
Actions: []DashboardAction{
|
||||
{
|
||||
Type: DashboardActionTypeFetch,
|
||||
Title: "Test Action",
|
||||
Fetch: &DashboardFetchOptions{
|
||||
Method: DashboardHttpRequestMethodGET,
|
||||
Url: "http://example.com",
|
||||
QueryParams: [][]string{
|
||||
{"param1", "value1", "extra1"},
|
||||
{"param2", "value2"},
|
||||
},
|
||||
Headers: [][]string{
|
||||
{"header1", "value1", "extra1", "extra2"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &Dashboard{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Dashboard",
|
||||
APIVersion: "v2beta1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-dashboard",
|
||||
},
|
||||
Spec: DashboardSpec{
|
||||
Elements: map[string]DashboardElement{
|
||||
"panel1": {
|
||||
PanelKind: &DashboardPanelKind{
|
||||
Spec: DashboardPanelSpec{
|
||||
VizConfig: DashboardVizConfigKind{
|
||||
Spec: DashboardVizConfigSpec{
|
||||
FieldConfig: DashboardFieldConfigSource{
|
||||
Defaults: DashboardFieldConfig{
|
||||
Actions: []DashboardAction{
|
||||
{
|
||||
Type: DashboardActionTypeFetch,
|
||||
Title: "Test Action",
|
||||
Fetch: &DashboardFetchOptions{
|
||||
Method: DashboardHttpRequestMethodGET,
|
||||
Url: "http://example.com",
|
||||
QueryParams: [][]string{
|
||||
{"param1", "value1"},
|
||||
{"param2", "value2"},
|
||||
},
|
||||
Headers: [][]string{
|
||||
{"header1", "value1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "dashboard with panel having no actions",
|
||||
dashboard: &Dashboard{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Dashboard",
|
||||
APIVersion: "v2beta1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-dashboard",
|
||||
},
|
||||
Spec: DashboardSpec{
|
||||
Elements: map[string]DashboardElement{
|
||||
"panel1": {
|
||||
PanelKind: &DashboardPanelKind{
|
||||
Spec: DashboardPanelSpec{
|
||||
VizConfig: DashboardVizConfigKind{
|
||||
Spec: DashboardVizConfigSpec{
|
||||
FieldConfig: DashboardFieldConfigSource{
|
||||
Defaults: DashboardFieldConfig{
|
||||
Actions: nil,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &Dashboard{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Dashboard",
|
||||
APIVersion: "v2beta1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-dashboard",
|
||||
},
|
||||
Spec: DashboardSpec{
|
||||
Elements: map[string]DashboardElement{
|
||||
"panel1": {
|
||||
PanelKind: &DashboardPanelKind{
|
||||
Spec: DashboardPanelSpec{
|
||||
VizConfig: DashboardVizConfigKind{
|
||||
Spec: DashboardVizConfigSpec{
|
||||
FieldConfig: DashboardFieldConfigSource{
|
||||
Defaults: DashboardFieldConfig{
|
||||
Actions: nil,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Create a deep copy to avoid modifying the original
|
||||
dashboardCopy := deepCopyDashboard(tt.dashboard)
|
||||
|
||||
validateAndTrimActionArrays(dashboardCopy)
|
||||
assert.Equal(t, tt.expected, dashboardCopy)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to create a deep copy of a Dashboard for testing
|
||||
func deepCopyDashboard(original *Dashboard) *Dashboard {
|
||||
if original == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
result := &Dashboard{
|
||||
TypeMeta: original.TypeMeta,
|
||||
ObjectMeta: original.ObjectMeta,
|
||||
Spec: DashboardSpec{
|
||||
Elements: make(map[string]DashboardElement),
|
||||
},
|
||||
Status: original.Status,
|
||||
}
|
||||
|
||||
for key, element := range original.Spec.Elements {
|
||||
elementCopy := element
|
||||
|
||||
if element.PanelKind != nil {
|
||||
panelCopy := *element.PanelKind
|
||||
elementCopy.PanelKind = &panelCopy
|
||||
|
||||
if element.PanelKind.Spec.VizConfig.Spec.FieldConfig.Defaults.Actions != nil {
|
||||
actions := element.PanelKind.Spec.VizConfig.Spec.FieldConfig.Defaults.Actions
|
||||
actionsCopy := make([]DashboardAction, len(actions))
|
||||
|
||||
for j, action := range actions {
|
||||
actionsCopy[j] = action
|
||||
|
||||
// Deep copy fetch options
|
||||
if action.Fetch != nil {
|
||||
fetchCopy := *action.Fetch
|
||||
if action.Fetch.QueryParams != nil {
|
||||
fetchCopy.QueryParams = make([][]string, len(action.Fetch.QueryParams))
|
||||
for k, param := range action.Fetch.QueryParams {
|
||||
fetchCopy.QueryParams[k] = make([]string, len(param))
|
||||
copy(fetchCopy.QueryParams[k], param)
|
||||
}
|
||||
}
|
||||
if action.Fetch.Headers != nil {
|
||||
fetchCopy.Headers = make([][]string, len(action.Fetch.Headers))
|
||||
for k, header := range action.Fetch.Headers {
|
||||
fetchCopy.Headers[k] = make([]string, len(header))
|
||||
copy(fetchCopy.Headers[k], header)
|
||||
}
|
||||
}
|
||||
actionsCopy[j].Fetch = &fetchCopy
|
||||
}
|
||||
|
||||
// Deep copy infinity options
|
||||
if action.Infinity != nil {
|
||||
infinityCopy := *action.Infinity
|
||||
if action.Infinity.QueryParams != nil {
|
||||
infinityCopy.QueryParams = make([][]string, len(action.Infinity.QueryParams))
|
||||
for k, param := range action.Infinity.QueryParams {
|
||||
infinityCopy.QueryParams[k] = make([]string, len(param))
|
||||
copy(infinityCopy.QueryParams[k], param)
|
||||
}
|
||||
}
|
||||
if action.Infinity.Headers != nil {
|
||||
infinityCopy.Headers = make([][]string, len(action.Infinity.Headers))
|
||||
for k, header := range action.Infinity.Headers {
|
||||
infinityCopy.Headers[k] = make([]string, len(header))
|
||||
copy(infinityCopy.Headers[k], header)
|
||||
}
|
||||
}
|
||||
actionsCopy[j].Infinity = &infinityCopy
|
||||
}
|
||||
}
|
||||
|
||||
elementCopy.PanelKind.Spec.VizConfig.Spec.FieldConfig.Defaults.Actions = actionsCopy
|
||||
}
|
||||
}
|
||||
|
||||
if element.LibraryPanelKind != nil {
|
||||
libraryCopy := *element.LibraryPanelKind
|
||||
elementCopy.LibraryPanelKind = &libraryCopy
|
||||
}
|
||||
|
||||
result.Spec.Elements[key] = elementCopy
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
@@ -18,6 +18,8 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.AnnotationPermission": schema_pkg_apis_dashboard_v2alpha1_AnnotationPermission(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.Dashboard": schema_pkg_apis_dashboard_v2alpha1_Dashboard(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardAccess": schema_pkg_apis_dashboard_v2alpha1_DashboardAccess(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardAction": schema_pkg_apis_dashboard_v2alpha1_DashboardAction(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardActionVariable": schema_pkg_apis_dashboard_v2alpha1_DashboardActionVariable(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardAdHocFilterWithLabels": schema_pkg_apis_dashboard_v2alpha1_DashboardAdHocFilterWithLabels(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardAdhocVariableKind": schema_pkg_apis_dashboard_v2alpha1_DashboardAdhocVariableKind(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardAdhocVariableSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardAdhocVariableSpec(ref),
|
||||
@@ -52,6 +54,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardDatasourceVariableSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardDatasourceVariableSpec(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardDynamicConfigValue": schema_pkg_apis_dashboard_v2alpha1_DashboardDynamicConfigValue(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardElementReference": schema_pkg_apis_dashboard_v2alpha1_DashboardElementReference(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardFetchOptions": schema_pkg_apis_dashboard_v2alpha1_DashboardFetchOptions(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardFieldColor": schema_pkg_apis_dashboard_v2alpha1_DashboardFieldColor(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardFieldConfig": schema_pkg_apis_dashboard_v2alpha1_DashboardFieldConfig(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardFieldConfigSource": schema_pkg_apis_dashboard_v2alpha1_DashboardFieldConfigSource(ref),
|
||||
@@ -63,6 +66,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardGridLayoutSpec(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardGroupByVariableKind": schema_pkg_apis_dashboard_v2alpha1_DashboardGroupByVariableKind(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardGroupByVariableSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardGroupByVariableSpec(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardInfinityOptions": schema_pkg_apis_dashboard_v2alpha1_DashboardInfinityOptions(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardIntervalVariableKind": schema_pkg_apis_dashboard_v2alpha1_DashboardIntervalVariableKind(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardIntervalVariableSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardIntervalVariableSpec(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardJSONCodec": schema_pkg_apis_dashboard_v2alpha1_DashboardJSONCodec(ref),
|
||||
@@ -109,6 +113,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardTimeRangeOption": schema_pkg_apis_dashboard_v2alpha1_DashboardTimeRangeOption(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardTimeSettingsSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardTimeSettingsSpec(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardTransformationKind": schema_pkg_apis_dashboard_v2alpha1_DashboardTransformationKind(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardV2alpha1ActionStyle": schema_pkg_apis_dashboard_v2alpha1_DashboardV2alpha1ActionStyle(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardV2alpha1FieldConfigSourceOverrides": schema_pkg_apis_dashboard_v2alpha1_DashboardV2alpha1FieldConfigSourceOverrides(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardV2alpha1RangeMapOptions": schema_pkg_apis_dashboard_v2alpha1_DashboardV2alpha1RangeMapOptions(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardV2alpha1RegexMapOptions": schema_pkg_apis_dashboard_v2alpha1_DashboardV2alpha1RegexMapOptions(ref),
|
||||
@@ -309,6 +314,109 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardAccess(ref common.ReferenceCall
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_dashboard_v2alpha1_DashboardAction(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"type": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"title": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"fetch": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardFetchOptions"),
|
||||
},
|
||||
},
|
||||
"infinity": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardInfinityOptions"),
|
||||
},
|
||||
},
|
||||
"confirmation": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"oneClick": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"boolean"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"variables": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardActionVariable"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"style": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardV2alpha1ActionStyle"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"type", "title"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardActionVariable", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardFetchOptions", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardInfinityOptions", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardV2alpha1ActionStyle"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_dashboard_v2alpha1_DashboardActionVariable(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"key": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"name": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"type": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"key", "name", "type"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_dashboard_v2alpha1_DashboardAdHocFilterWithLabels(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
@@ -1805,6 +1913,82 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardElementReference(ref common.Ref
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_dashboard_v2alpha1_DashboardFetchOptions(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"method": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"url": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"body": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"queryParams": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "These are 2D arrays of strings, each representing a key-value pair We are defining them this way because we can't generate a go struct that that would have exactly two strings in each sub-array",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"headers": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"method", "url"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_dashboard_v2alpha1_DashboardFieldColor(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
@@ -1957,6 +2141,20 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardFieldConfig(ref common.Referenc
|
||||
},
|
||||
},
|
||||
},
|
||||
"actions": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Define interactive HTTP requests that can be triggered from data visualizations.",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardAction"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"noValue": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Alternative to empty string",
|
||||
@@ -1983,7 +2181,7 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardFieldConfig(ref common.Referenc
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardFieldColor", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardThresholdsConfig", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap"},
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardAction", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardFieldColor", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardThresholdsConfig", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap"},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2345,6 +2543,89 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardGroupByVariableSpec(ref common.
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_dashboard_v2alpha1_DashboardInfinityOptions(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"method": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"url": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"body": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"queryParams": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "These are 2D arrays of strings, each representing a key-value pair We are defining them this way because we can't generate a go struct that that would have exactly two strings in each sub-array",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"datasourceUid": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"headers": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"method", "url", "datasourceUid"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_dashboard_v2alpha1_DashboardIntervalVariableKind(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
@@ -4337,6 +4618,24 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardTransformationKind(ref common.R
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_dashboard_v2alpha1_DashboardV2alpha1ActionStyle(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"backgroundColor": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_dashboard_v2alpha1_DashboardV2alpha1FieldConfigSourceOverrides(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
|
||||
+6
@@ -1,3 +1,4 @@
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardAction,Variables
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardAdHocFilterWithLabels,ValueLabels
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardAdHocFilterWithLabels,Values
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardAdhocVariableSpec,BaseFilters
|
||||
@@ -9,11 +10,16 @@ API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardCustomVariableSpec,Options
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardDashboardLink,Tags
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardDatasourceVariableSpec,Options
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardFetchOptions,Headers
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardFetchOptions,QueryParams
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardFieldConfig,Actions
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardFieldConfig,Links
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardFieldConfig,Mappings
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardFieldConfigSource,Overrides
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardGridLayoutSpec,Items
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardGroupByVariableSpec,Options
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardInfinityOptions,Headers
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardInfinityOptions,QueryParams
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardIntervalVariableSpec,Options
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardMetadata,Finalizers
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardPanelSpec,Links
|
||||
|
||||
@@ -223,6 +223,9 @@ FieldConfig: {
|
||||
// The behavior when clicking on a result
|
||||
links?: [...]
|
||||
|
||||
// Define interactive HTTP requests that can be triggered from data visualizations.
|
||||
actions?: [...Action]
|
||||
|
||||
// Alternative to empty string
|
||||
noValue?: string
|
||||
|
||||
@@ -366,6 +369,48 @@ FieldColor: {
|
||||
// Dashboard Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource)
|
||||
DashboardLinkType: "link" | "dashboards"
|
||||
|
||||
ActionType: "fetch" | "infinity"
|
||||
|
||||
FetchOptions: {
|
||||
method: HttpRequestMethod
|
||||
url: string
|
||||
body?: string
|
||||
// These are 2D arrays of strings, each representing a key-value pair
|
||||
// We are defining them this way because we can't generate a go struct that
|
||||
// that would have exactly two strings in each sub-array
|
||||
queryParams?: [...[...string]]
|
||||
headers?: [...[...string]]
|
||||
}
|
||||
|
||||
InfinityOptions: FetchOptions & {
|
||||
datasourceUid: string
|
||||
}
|
||||
|
||||
HttpRequestMethod: "GET" | "PUT" | "POST" | "DELETE" | "PATCH"
|
||||
|
||||
// Action variable type
|
||||
ActionVariableType: "string"
|
||||
|
||||
ActionVariable: {
|
||||
key: string
|
||||
name: string
|
||||
type: ActionVariableType
|
||||
}
|
||||
|
||||
Action: {
|
||||
type: ActionType
|
||||
title: string
|
||||
fetch?: FetchOptions
|
||||
infinity?: InfinityOptions
|
||||
confirmation?: string
|
||||
oneClick?: bool
|
||||
variables?: [...ActionVariable]
|
||||
style?: {
|
||||
backgroundColor?: string
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --- Common types ---
|
||||
Kind: {
|
||||
kind: string
|
||||
|
||||
@@ -386,6 +386,8 @@ type DashboardFieldConfig struct {
|
||||
Color *DashboardFieldColor `json:"color,omitempty"`
|
||||
// The behavior when clicking on a result
|
||||
Links []interface{} `json:"links,omitempty"`
|
||||
// Define interactive HTTP requests that can be triggered from data visualizations.
|
||||
Actions []DashboardAction `json:"actions,omitempty"`
|
||||
// Alternative to empty string
|
||||
NoValue *string `json:"noValue,omitempty"`
|
||||
// custom is specified by the FieldConfig field
|
||||
@@ -617,6 +619,95 @@ const (
|
||||
DashboardFieldColorSeriesByModeLast DashboardFieldColorSeriesByMode = "last"
|
||||
)
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type DashboardAction struct {
|
||||
Type DashboardActionType `json:"type"`
|
||||
Title string `json:"title"`
|
||||
Fetch *DashboardFetchOptions `json:"fetch,omitempty"`
|
||||
Infinity *DashboardInfinityOptions `json:"infinity,omitempty"`
|
||||
Confirmation *string `json:"confirmation,omitempty"`
|
||||
OneClick *bool `json:"oneClick,omitempty"`
|
||||
Variables []DashboardActionVariable `json:"variables,omitempty"`
|
||||
Style *DashboardV2beta1ActionStyle `json:"style,omitempty"`
|
||||
}
|
||||
|
||||
// NewDashboardAction creates a new DashboardAction object.
|
||||
func NewDashboardAction() *DashboardAction {
|
||||
return &DashboardAction{}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type DashboardActionType string
|
||||
|
||||
const (
|
||||
DashboardActionTypeFetch DashboardActionType = "fetch"
|
||||
DashboardActionTypeInfinity DashboardActionType = "infinity"
|
||||
)
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type DashboardFetchOptions struct {
|
||||
Method DashboardHttpRequestMethod `json:"method"`
|
||||
Url string `json:"url"`
|
||||
Body *string `json:"body,omitempty"`
|
||||
// These are 2D arrays of strings, each representing a key-value pair
|
||||
// We are defining them this way because we can't generate a go struct that
|
||||
// that would have exactly two strings in each sub-array
|
||||
QueryParams [][]string `json:"queryParams,omitempty"`
|
||||
Headers [][]string `json:"headers,omitempty"`
|
||||
}
|
||||
|
||||
// NewDashboardFetchOptions creates a new DashboardFetchOptions object.
|
||||
func NewDashboardFetchOptions() *DashboardFetchOptions {
|
||||
return &DashboardFetchOptions{}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type DashboardHttpRequestMethod string
|
||||
|
||||
const (
|
||||
DashboardHttpRequestMethodGET DashboardHttpRequestMethod = "GET"
|
||||
DashboardHttpRequestMethodPUT DashboardHttpRequestMethod = "PUT"
|
||||
DashboardHttpRequestMethodPOST DashboardHttpRequestMethod = "POST"
|
||||
DashboardHttpRequestMethodDELETE DashboardHttpRequestMethod = "DELETE"
|
||||
DashboardHttpRequestMethodPATCH DashboardHttpRequestMethod = "PATCH"
|
||||
)
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type DashboardInfinityOptions struct {
|
||||
Method DashboardHttpRequestMethod `json:"method"`
|
||||
Url string `json:"url"`
|
||||
Body *string `json:"body,omitempty"`
|
||||
// These are 2D arrays of strings, each representing a key-value pair
|
||||
// We are defining them this way because we can't generate a go struct that
|
||||
// that would have exactly two strings in each sub-array
|
||||
QueryParams [][]string `json:"queryParams,omitempty"`
|
||||
DatasourceUid string `json:"datasourceUid"`
|
||||
Headers [][]string `json:"headers,omitempty"`
|
||||
}
|
||||
|
||||
// NewDashboardInfinityOptions creates a new DashboardInfinityOptions object.
|
||||
func NewDashboardInfinityOptions() *DashboardInfinityOptions {
|
||||
return &DashboardInfinityOptions{}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type DashboardActionVariable struct {
|
||||
Key string `json:"key"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
// NewDashboardActionVariable creates a new DashboardActionVariable object.
|
||||
func NewDashboardActionVariable() *DashboardActionVariable {
|
||||
return &DashboardActionVariable{
|
||||
Type: DashboardActionVariableType,
|
||||
}
|
||||
}
|
||||
|
||||
// Action variable type
|
||||
// +k8s:openapi-gen=true
|
||||
const DashboardActionVariableType = "string"
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type DashboardDynamicConfigValue struct {
|
||||
Id string `json:"id"`
|
||||
@@ -1853,6 +1944,16 @@ func NewDashboardV2beta1SpecialValueMapOptions() *DashboardV2beta1SpecialValueMa
|
||||
}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type DashboardV2beta1ActionStyle struct {
|
||||
BackgroundColor *string `json:"backgroundColor,omitempty"`
|
||||
}
|
||||
|
||||
// NewDashboardV2beta1ActionStyle creates a new DashboardV2beta1ActionStyle object.
|
||||
func NewDashboardV2beta1ActionStyle() *DashboardV2beta1ActionStyle {
|
||||
return &DashboardV2beta1ActionStyle{}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type DashboardV2beta1GroupByVariableKindDatasource struct {
|
||||
Name *string `json:"name,omitempty"`
|
||||
|
||||
@@ -23,6 +23,9 @@ func ValidateDashboardSpec(obj *Dashboard) field.ErrorList {
|
||||
}
|
||||
}
|
||||
|
||||
// Custom validation for action query params and headers
|
||||
validateAndTrimActionArrays(obj)
|
||||
|
||||
if err := cuejson.Validate(data, getCueSchema()); err != nil {
|
||||
errs := field.ErrorList{}
|
||||
|
||||
@@ -60,6 +63,61 @@ func ValidateDashboardSpec(obj *Dashboard) field.ErrorList {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validates and trims action query params and headers to exactly 2 elements each
|
||||
// This is because we couldn't generate with cue a go struct that would have exactly two strings in each sub-array
|
||||
func validateAndTrimActionArrays(obj *Dashboard) {
|
||||
for _, element := range obj.Spec.Elements {
|
||||
if element.PanelKind != nil {
|
||||
panelElement := element.PanelKind
|
||||
if panelElement.Spec.VizConfig.Spec.FieldConfig.Defaults.Actions != nil {
|
||||
processActions(panelElement.Spec.VizConfig.Spec.FieldConfig.Defaults.Actions)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to process action arrays
|
||||
func processActions(actions []DashboardAction) {
|
||||
for _, action := range actions {
|
||||
// Process FetchOptions if present
|
||||
if action.Fetch != nil {
|
||||
if action.Fetch.QueryParams != nil {
|
||||
action.Fetch.QueryParams = trimStringArrays(action.Fetch.QueryParams)
|
||||
}
|
||||
if action.Fetch.Headers != nil {
|
||||
action.Fetch.Headers = trimStringArrays(action.Fetch.Headers)
|
||||
}
|
||||
}
|
||||
|
||||
// Process InfinityOptions if present
|
||||
if action.Infinity != nil {
|
||||
if action.Infinity.QueryParams != nil {
|
||||
action.Infinity.QueryParams = trimStringArrays(action.Infinity.QueryParams)
|
||||
}
|
||||
if action.Infinity.Headers != nil {
|
||||
action.Infinity.Headers = trimStringArrays(action.Infinity.Headers)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to trim 2D string arrays to exactly 2 elements per sub-array
|
||||
func trimStringArrays(arrays [][]string) [][]string {
|
||||
if arrays == nil {
|
||||
return arrays
|
||||
}
|
||||
|
||||
result := make([][]string, len(arrays))
|
||||
for i, arr := range arrays {
|
||||
if len(arr) > 2 {
|
||||
result[i] = arr[:2]
|
||||
} else {
|
||||
result[i] = arr
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func formatErrorPath(path []string) string {
|
||||
return strings.Join(path, ".")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,495 @@
|
||||
package v2beta1
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func TestTrimStringArrays(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input [][]string
|
||||
expected [][]string
|
||||
}{
|
||||
{
|
||||
name: "nil input",
|
||||
input: nil,
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
name: "empty input",
|
||||
input: [][]string{},
|
||||
expected: [][]string{},
|
||||
},
|
||||
{
|
||||
name: "arrays with exactly 2 elements",
|
||||
input: [][]string{{"key1", "value1"}, {"key2", "value2"}},
|
||||
expected: [][]string{{"key1", "value1"}, {"key2", "value2"}},
|
||||
},
|
||||
{
|
||||
name: "arrays with less than 2 elements",
|
||||
input: [][]string{{"key1"}, {}},
|
||||
expected: [][]string{{"key1"}, {}},
|
||||
},
|
||||
{
|
||||
name: "arrays with more than 2 elements",
|
||||
input: [][]string{{"key1", "value1", "extra1"}, {"key2", "value2", "extra2", "extra3"}},
|
||||
expected: [][]string{{"key1", "value1"}, {"key2", "value2"}},
|
||||
},
|
||||
{
|
||||
name: "mixed arrays",
|
||||
input: [][]string{{"key1"}, {"key2", "value2"}, {"key3", "value3", "extra"}},
|
||||
expected: [][]string{{"key1"}, {"key2", "value2"}, {"key3", "value3"}},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := trimStringArrays(tt.input)
|
||||
assert.Equal(t, tt.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessActions(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
actions []DashboardAction
|
||||
expected []DashboardAction
|
||||
}{
|
||||
{
|
||||
name: "empty actions",
|
||||
actions: []DashboardAction{},
|
||||
expected: []DashboardAction{},
|
||||
},
|
||||
{
|
||||
name: "action with fetch options having oversized arrays",
|
||||
actions: []DashboardAction{
|
||||
{
|
||||
Type: DashboardActionTypeFetch,
|
||||
Title: "Test Fetch",
|
||||
Fetch: &DashboardFetchOptions{
|
||||
Method: DashboardHttpRequestMethodGET,
|
||||
Url: "http://example.com",
|
||||
QueryParams: [][]string{
|
||||
{"param1", "value1", "extra1"},
|
||||
{"param2", "value2"},
|
||||
},
|
||||
Headers: [][]string{
|
||||
{"header1", "value1", "extra1", "extra2"},
|
||||
{"header2", "value2"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: []DashboardAction{
|
||||
{
|
||||
Type: DashboardActionTypeFetch,
|
||||
Title: "Test Fetch",
|
||||
Fetch: &DashboardFetchOptions{
|
||||
Method: DashboardHttpRequestMethodGET,
|
||||
Url: "http://example.com",
|
||||
QueryParams: [][]string{
|
||||
{"param1", "value1"},
|
||||
{"param2", "value2"},
|
||||
},
|
||||
Headers: [][]string{
|
||||
{"header1", "value1"},
|
||||
{"header2", "value2"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "action with infinity options having oversized arrays",
|
||||
actions: []DashboardAction{
|
||||
{
|
||||
Type: DashboardActionTypeInfinity,
|
||||
Title: "Test Infinity",
|
||||
Infinity: &DashboardInfinityOptions{
|
||||
Method: DashboardHttpRequestMethodPOST,
|
||||
Url: "http://example.com",
|
||||
DatasourceUid: "test-uid",
|
||||
QueryParams: [][]string{
|
||||
{"param1", "value1", "extra1"},
|
||||
{"param2", "value2"},
|
||||
},
|
||||
Headers: [][]string{
|
||||
{"header1", "value1", "extra1", "extra2"},
|
||||
{"header2", "value2"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: []DashboardAction{
|
||||
{
|
||||
Type: DashboardActionTypeInfinity,
|
||||
Title: "Test Infinity",
|
||||
Infinity: &DashboardInfinityOptions{
|
||||
Method: DashboardHttpRequestMethodPOST,
|
||||
Url: "http://example.com",
|
||||
DatasourceUid: "test-uid",
|
||||
QueryParams: [][]string{
|
||||
{"param1", "value1"},
|
||||
{"param2", "value2"},
|
||||
},
|
||||
Headers: [][]string{
|
||||
{"header1", "value1"},
|
||||
{"header2", "value2"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "action without fetch or infinity options",
|
||||
actions: []DashboardAction{
|
||||
{
|
||||
Type: DashboardActionTypeFetch,
|
||||
Title: "Test Action",
|
||||
},
|
||||
},
|
||||
expected: []DashboardAction{
|
||||
{
|
||||
Type: DashboardActionTypeFetch,
|
||||
Title: "Test Action",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Create a copy to avoid modifying the original
|
||||
actionsCopy := make([]DashboardAction, len(tt.actions))
|
||||
for i, action := range tt.actions {
|
||||
actionsCopy[i] = action
|
||||
// Deep copy the fetch options if they exist
|
||||
if action.Fetch != nil {
|
||||
fetchCopy := *action.Fetch
|
||||
if action.Fetch.QueryParams != nil {
|
||||
fetchCopy.QueryParams = make([][]string, len(action.Fetch.QueryParams))
|
||||
for j, param := range action.Fetch.QueryParams {
|
||||
fetchCopy.QueryParams[j] = make([]string, len(param))
|
||||
copy(fetchCopy.QueryParams[j], param)
|
||||
}
|
||||
}
|
||||
if action.Fetch.Headers != nil {
|
||||
fetchCopy.Headers = make([][]string, len(action.Fetch.Headers))
|
||||
for j, header := range action.Fetch.Headers {
|
||||
fetchCopy.Headers[j] = make([]string, len(header))
|
||||
copy(fetchCopy.Headers[j], header)
|
||||
}
|
||||
}
|
||||
actionsCopy[i].Fetch = &fetchCopy
|
||||
}
|
||||
// Deep copy the infinity options if they exist
|
||||
if action.Infinity != nil {
|
||||
infinityCopy := *action.Infinity
|
||||
if action.Infinity.QueryParams != nil {
|
||||
infinityCopy.QueryParams = make([][]string, len(action.Infinity.QueryParams))
|
||||
for j, param := range action.Infinity.QueryParams {
|
||||
infinityCopy.QueryParams[j] = make([]string, len(param))
|
||||
copy(infinityCopy.QueryParams[j], param)
|
||||
}
|
||||
}
|
||||
if action.Infinity.Headers != nil {
|
||||
infinityCopy.Headers = make([][]string, len(action.Infinity.Headers))
|
||||
for j, header := range action.Infinity.Headers {
|
||||
infinityCopy.Headers[j] = make([]string, len(header))
|
||||
copy(infinityCopy.Headers[j], header)
|
||||
}
|
||||
}
|
||||
actionsCopy[i].Infinity = &infinityCopy
|
||||
}
|
||||
}
|
||||
|
||||
processActions(actionsCopy)
|
||||
assert.Equal(t, tt.expected, actionsCopy)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateAndTrimActionArrays(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
dashboard *Dashboard
|
||||
expected *Dashboard
|
||||
}{
|
||||
{
|
||||
name: "dashboard with no elements",
|
||||
dashboard: &Dashboard{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Dashboard",
|
||||
APIVersion: "v2beta1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-dashboard",
|
||||
},
|
||||
Spec: DashboardSpec{
|
||||
Elements: map[string]DashboardElement{},
|
||||
},
|
||||
},
|
||||
expected: &Dashboard{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Dashboard",
|
||||
APIVersion: "v2beta1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-dashboard",
|
||||
},
|
||||
Spec: DashboardSpec{
|
||||
Elements: map[string]DashboardElement{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "dashboard with panel having actions with oversized arrays",
|
||||
dashboard: &Dashboard{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Dashboard",
|
||||
APIVersion: "v2beta1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-dashboard",
|
||||
},
|
||||
Spec: DashboardSpec{
|
||||
Elements: map[string]DashboardElement{
|
||||
"panel1": {
|
||||
PanelKind: &DashboardPanelKind{
|
||||
Spec: DashboardPanelSpec{
|
||||
VizConfig: DashboardVizConfigKind{
|
||||
Spec: DashboardVizConfigSpec{
|
||||
FieldConfig: DashboardFieldConfigSource{
|
||||
Defaults: DashboardFieldConfig{
|
||||
Actions: []DashboardAction{
|
||||
{
|
||||
Type: DashboardActionTypeFetch,
|
||||
Title: "Test Action",
|
||||
Fetch: &DashboardFetchOptions{
|
||||
Method: DashboardHttpRequestMethodGET,
|
||||
Url: "http://example.com",
|
||||
QueryParams: [][]string{
|
||||
{"param1", "value1", "extra1"},
|
||||
{"param2", "value2"},
|
||||
},
|
||||
Headers: [][]string{
|
||||
{"header1", "value1", "extra1", "extra2"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &Dashboard{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Dashboard",
|
||||
APIVersion: "v2beta1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-dashboard",
|
||||
},
|
||||
Spec: DashboardSpec{
|
||||
Elements: map[string]DashboardElement{
|
||||
"panel1": {
|
||||
PanelKind: &DashboardPanelKind{
|
||||
Spec: DashboardPanelSpec{
|
||||
VizConfig: DashboardVizConfigKind{
|
||||
Spec: DashboardVizConfigSpec{
|
||||
FieldConfig: DashboardFieldConfigSource{
|
||||
Defaults: DashboardFieldConfig{
|
||||
Actions: []DashboardAction{
|
||||
{
|
||||
Type: DashboardActionTypeFetch,
|
||||
Title: "Test Action",
|
||||
Fetch: &DashboardFetchOptions{
|
||||
Method: DashboardHttpRequestMethodGET,
|
||||
Url: "http://example.com",
|
||||
QueryParams: [][]string{
|
||||
{"param1", "value1"},
|
||||
{"param2", "value2"},
|
||||
},
|
||||
Headers: [][]string{
|
||||
{"header1", "value1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "dashboard with panel having no actions",
|
||||
dashboard: &Dashboard{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Dashboard",
|
||||
APIVersion: "v2beta1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-dashboard",
|
||||
},
|
||||
Spec: DashboardSpec{
|
||||
Elements: map[string]DashboardElement{
|
||||
"panel1": {
|
||||
PanelKind: &DashboardPanelKind{
|
||||
Spec: DashboardPanelSpec{
|
||||
VizConfig: DashboardVizConfigKind{
|
||||
Spec: DashboardVizConfigSpec{
|
||||
FieldConfig: DashboardFieldConfigSource{
|
||||
Defaults: DashboardFieldConfig{
|
||||
Actions: nil,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &Dashboard{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Dashboard",
|
||||
APIVersion: "v2beta1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-dashboard",
|
||||
},
|
||||
Spec: DashboardSpec{
|
||||
Elements: map[string]DashboardElement{
|
||||
"panel1": {
|
||||
PanelKind: &DashboardPanelKind{
|
||||
Spec: DashboardPanelSpec{
|
||||
VizConfig: DashboardVizConfigKind{
|
||||
Spec: DashboardVizConfigSpec{
|
||||
FieldConfig: DashboardFieldConfigSource{
|
||||
Defaults: DashboardFieldConfig{
|
||||
Actions: nil,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Create a deep copy to avoid modifying the original
|
||||
dashboardCopy := deepCopyDashboard(tt.dashboard)
|
||||
|
||||
validateAndTrimActionArrays(dashboardCopy)
|
||||
assert.Equal(t, tt.expected, dashboardCopy)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to create a deep copy of a Dashboard for testing
|
||||
func deepCopyDashboard(original *Dashboard) *Dashboard {
|
||||
if original == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
result := &Dashboard{
|
||||
TypeMeta: original.TypeMeta,
|
||||
ObjectMeta: original.ObjectMeta,
|
||||
Spec: DashboardSpec{
|
||||
Elements: make(map[string]DashboardElement),
|
||||
},
|
||||
Status: original.Status,
|
||||
}
|
||||
|
||||
for key, element := range original.Spec.Elements {
|
||||
elementCopy := element
|
||||
|
||||
if element.PanelKind != nil {
|
||||
panelCopy := *element.PanelKind
|
||||
elementCopy.PanelKind = &panelCopy
|
||||
|
||||
if element.PanelKind.Spec.VizConfig.Spec.FieldConfig.Defaults.Actions != nil {
|
||||
actions := element.PanelKind.Spec.VizConfig.Spec.FieldConfig.Defaults.Actions
|
||||
actionsCopy := make([]DashboardAction, len(actions))
|
||||
|
||||
for j, action := range actions {
|
||||
actionsCopy[j] = action
|
||||
|
||||
// Deep copy fetch options
|
||||
if action.Fetch != nil {
|
||||
fetchCopy := *action.Fetch
|
||||
if action.Fetch.QueryParams != nil {
|
||||
fetchCopy.QueryParams = make([][]string, len(action.Fetch.QueryParams))
|
||||
for k, param := range action.Fetch.QueryParams {
|
||||
fetchCopy.QueryParams[k] = make([]string, len(param))
|
||||
copy(fetchCopy.QueryParams[k], param)
|
||||
}
|
||||
}
|
||||
if action.Fetch.Headers != nil {
|
||||
fetchCopy.Headers = make([][]string, len(action.Fetch.Headers))
|
||||
for k, header := range action.Fetch.Headers {
|
||||
fetchCopy.Headers[k] = make([]string, len(header))
|
||||
copy(fetchCopy.Headers[k], header)
|
||||
}
|
||||
}
|
||||
actionsCopy[j].Fetch = &fetchCopy
|
||||
}
|
||||
|
||||
// Deep copy infinity options
|
||||
if action.Infinity != nil {
|
||||
infinityCopy := *action.Infinity
|
||||
if action.Infinity.QueryParams != nil {
|
||||
infinityCopy.QueryParams = make([][]string, len(action.Infinity.QueryParams))
|
||||
for k, param := range action.Infinity.QueryParams {
|
||||
infinityCopy.QueryParams[k] = make([]string, len(param))
|
||||
copy(infinityCopy.QueryParams[k], param)
|
||||
}
|
||||
}
|
||||
if action.Infinity.Headers != nil {
|
||||
infinityCopy.Headers = make([][]string, len(action.Infinity.Headers))
|
||||
for k, header := range action.Infinity.Headers {
|
||||
infinityCopy.Headers[k] = make([]string, len(header))
|
||||
copy(infinityCopy.Headers[k], header)
|
||||
}
|
||||
}
|
||||
actionsCopy[j].Infinity = &infinityCopy
|
||||
}
|
||||
}
|
||||
|
||||
elementCopy.PanelKind.Spec.VizConfig.Spec.FieldConfig.Defaults.Actions = actionsCopy
|
||||
}
|
||||
}
|
||||
|
||||
if element.LibraryPanelKind != nil {
|
||||
libraryCopy := *element.LibraryPanelKind
|
||||
elementCopy.LibraryPanelKind = &libraryCopy
|
||||
}
|
||||
|
||||
result.Spec.Elements[key] = elementCopy
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
@@ -18,6 +18,8 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.AnnotationPermission": schema_pkg_apis_dashboard_v2beta1_AnnotationPermission(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.Dashboard": schema_pkg_apis_dashboard_v2beta1_Dashboard(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardAccess": schema_pkg_apis_dashboard_v2beta1_DashboardAccess(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardAction": schema_pkg_apis_dashboard_v2beta1_DashboardAction(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardActionVariable": schema_pkg_apis_dashboard_v2beta1_DashboardActionVariable(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardAdHocFilterWithLabels": schema_pkg_apis_dashboard_v2beta1_DashboardAdHocFilterWithLabels(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardAdhocVariableKind": schema_pkg_apis_dashboard_v2beta1_DashboardAdhocVariableKind(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardAdhocVariableSpec": schema_pkg_apis_dashboard_v2beta1_DashboardAdhocVariableSpec(ref),
|
||||
@@ -51,6 +53,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardDatasourceVariableSpec": schema_pkg_apis_dashboard_v2beta1_DashboardDatasourceVariableSpec(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardDynamicConfigValue": schema_pkg_apis_dashboard_v2beta1_DashboardDynamicConfigValue(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardElementReference": schema_pkg_apis_dashboard_v2beta1_DashboardElementReference(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardFetchOptions": schema_pkg_apis_dashboard_v2beta1_DashboardFetchOptions(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardFieldColor": schema_pkg_apis_dashboard_v2beta1_DashboardFieldColor(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardFieldConfig": schema_pkg_apis_dashboard_v2beta1_DashboardFieldConfig(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardFieldConfigSource": schema_pkg_apis_dashboard_v2beta1_DashboardFieldConfigSource(ref),
|
||||
@@ -62,6 +65,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardGridLayoutSpec": schema_pkg_apis_dashboard_v2beta1_DashboardGridLayoutSpec(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardGroupByVariableKind": schema_pkg_apis_dashboard_v2beta1_DashboardGroupByVariableKind(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardGroupByVariableSpec": schema_pkg_apis_dashboard_v2beta1_DashboardGroupByVariableSpec(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardInfinityOptions": schema_pkg_apis_dashboard_v2beta1_DashboardInfinityOptions(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardIntervalVariableKind": schema_pkg_apis_dashboard_v2beta1_DashboardIntervalVariableKind(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardIntervalVariableSpec": schema_pkg_apis_dashboard_v2beta1_DashboardIntervalVariableSpec(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardJSONCodec": schema_pkg_apis_dashboard_v2beta1_DashboardJSONCodec(ref),
|
||||
@@ -108,6 +112,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardTimeRangeOption": schema_pkg_apis_dashboard_v2beta1_DashboardTimeRangeOption(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardTimeSettingsSpec": schema_pkg_apis_dashboard_v2beta1_DashboardTimeSettingsSpec(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardTransformationKind": schema_pkg_apis_dashboard_v2beta1_DashboardTransformationKind(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardV2beta1ActionStyle": schema_pkg_apis_dashboard_v2beta1_DashboardV2beta1ActionStyle(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardV2beta1AdhocVariableKindDatasource": schema_pkg_apis_dashboard_v2beta1_DashboardV2beta1AdhocVariableKindDatasource(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardV2beta1DataQueryKindDatasource": schema_pkg_apis_dashboard_v2beta1_DashboardV2beta1DataQueryKindDatasource(ref),
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardV2beta1FieldConfigSourceOverrides": schema_pkg_apis_dashboard_v2beta1_DashboardV2beta1FieldConfigSourceOverrides(ref),
|
||||
@@ -311,6 +316,109 @@ func schema_pkg_apis_dashboard_v2beta1_DashboardAccess(ref common.ReferenceCallb
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_dashboard_v2beta1_DashboardAction(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"type": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"title": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"fetch": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardFetchOptions"),
|
||||
},
|
||||
},
|
||||
"infinity": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardInfinityOptions"),
|
||||
},
|
||||
},
|
||||
"confirmation": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"oneClick": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"boolean"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"variables": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardActionVariable"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"style": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardV2beta1ActionStyle"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"type", "title"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardActionVariable", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardFetchOptions", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardInfinityOptions", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardV2beta1ActionStyle"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_dashboard_v2beta1_DashboardActionVariable(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"key": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"name": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"type": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"key", "name", "type"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_dashboard_v2beta1_DashboardAdHocFilterWithLabels(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
@@ -1836,6 +1944,82 @@ func schema_pkg_apis_dashboard_v2beta1_DashboardElementReference(ref common.Refe
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_dashboard_v2beta1_DashboardFetchOptions(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"method": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"url": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"body": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"queryParams": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "These are 2D arrays of strings, each representing a key-value pair We are defining them this way because we can't generate a go struct that that would have exactly two strings in each sub-array",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"headers": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"method", "url"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_dashboard_v2beta1_DashboardFieldColor(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
@@ -1988,6 +2172,20 @@ func schema_pkg_apis_dashboard_v2beta1_DashboardFieldConfig(ref common.Reference
|
||||
},
|
||||
},
|
||||
},
|
||||
"actions": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Define interactive HTTP requests that can be triggered from data visualizations.",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardAction"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"noValue": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Alternative to empty string",
|
||||
@@ -2014,7 +2212,7 @@ func schema_pkg_apis_dashboard_v2beta1_DashboardFieldConfig(ref common.Reference
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardFieldColor", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardThresholdsConfig", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap"},
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardAction", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardFieldColor", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardThresholdsConfig", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap"},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2389,6 +2587,89 @@ func schema_pkg_apis_dashboard_v2beta1_DashboardGroupByVariableSpec(ref common.R
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_dashboard_v2beta1_DashboardInfinityOptions(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"method": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"url": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"body": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"queryParams": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "These are 2D arrays of strings, each representing a key-value pair We are defining them this way because we can't generate a go struct that that would have exactly two strings in each sub-array",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"datasourceUid": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"headers": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"method", "url", "datasourceUid"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_dashboard_v2beta1_DashboardIntervalVariableKind(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
@@ -4389,6 +4670,24 @@ func schema_pkg_apis_dashboard_v2beta1_DashboardTransformationKind(ref common.Re
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_dashboard_v2beta1_DashboardV2beta1ActionStyle(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"backgroundColor": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_dashboard_v2beta1_DashboardV2beta1AdhocVariableKindDatasource(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
|
||||
+6
@@ -1,3 +1,4 @@
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardAction,Variables
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardAdHocFilterWithLabels,ValueLabels
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardAdHocFilterWithLabels,Values
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardAdhocVariableSpec,BaseFilters
|
||||
@@ -9,11 +10,16 @@ API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardCustomVariableSpec,Options
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardDashboardLink,Tags
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardDatasourceVariableSpec,Options
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardFetchOptions,Headers
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardFetchOptions,QueryParams
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardFieldConfig,Actions
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardFieldConfig,Links
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardFieldConfig,Mappings
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardFieldConfigSource,Overrides
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardGridLayoutSpec,Items
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardGroupByVariableSpec,Options
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardInfinityOptions,Headers
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardInfinityOptions,QueryParams
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardIntervalVariableSpec,Options
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardMetadata,Finalizers
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardPanelSpec,Links
|
||||
|
||||
@@ -298,6 +298,59 @@ lineage: schemas: [{
|
||||
// - "inControlsMenu" renders the link in bottom part of the dashboard controls dropdown menu
|
||||
#DashboardLinkPlacement: "inControlsMenu" @cuetsy(kind="type")
|
||||
|
||||
// Dashboard action type
|
||||
#ActionType: "fetch" | "infinity" @cuetsy(kind="type")
|
||||
|
||||
// Fetch options
|
||||
#FetchOptions: {
|
||||
method: #HttpRequestMethod
|
||||
url: string
|
||||
body?: string
|
||||
// These are 2D arrays of strings, each representing a key-value pair
|
||||
// We are defining this way because we can't generate a go struct that
|
||||
// that would have exactly two strings in each sub-array
|
||||
queryParams?: [...[...string]]
|
||||
headers?: [...[...string]]
|
||||
} @cuetsy(kind="interface")
|
||||
|
||||
// Infinity options
|
||||
#InfinityOptions: {
|
||||
method: #HttpRequestMethod
|
||||
url: string
|
||||
body?: string
|
||||
// These are 2D arrays of strings, each representing a key-value pair
|
||||
// We are defining them this way because we can't generate a go struct that
|
||||
// that would have exactly two strings in each sub-array
|
||||
queryParams?: [...[...string]]
|
||||
headers?: [...[...string]]
|
||||
datasourceUid: string
|
||||
} @cuetsy(kind="interface")
|
||||
|
||||
#HttpRequestMethod: "GET" | "PUT" | "POST" | "DELETE" | "PATCH" @cuetsy(kind="type")
|
||||
|
||||
// Action variable type
|
||||
#ActionVariableType: "string" @cuetsy(kind="type")
|
||||
|
||||
#ActionVariable: {
|
||||
key: string
|
||||
name: string
|
||||
type: #ActionVariableType
|
||||
} @cuetsy(kind="interface")
|
||||
|
||||
// Dashboard action
|
||||
#Action: {
|
||||
type: #ActionType
|
||||
title: string
|
||||
fetch?: #FetchOptions
|
||||
infinity?: #InfinityOptions
|
||||
confirmation?: string
|
||||
oneClick?: bool
|
||||
variables?: [...#ActionVariable]
|
||||
style?: {
|
||||
backgroundColor?: string
|
||||
}
|
||||
} @cuetsy(kind="interface")
|
||||
|
||||
// Dashboard variable type
|
||||
// `query`: Query-generated list of values such as metric names, server names, sensor IDs, data centers, and so on.
|
||||
// `adhoc`: Key/value filters that are automatically added to all metric queries for a data source (Prometheus, Loki, InfluxDB, and Elasticsearch only).
|
||||
@@ -727,6 +780,9 @@ lineage: schemas: [{
|
||||
// The behavior when clicking on a result
|
||||
links?: [...] @grafanamaturity(NeedsExpertReview)
|
||||
|
||||
// Define interactive HTTP requests that can be triggered from data visualizations.
|
||||
actions?: [...#Action] @grafanamaturity(NeedsExpertReview)
|
||||
|
||||
// Alternative to empty string
|
||||
noValue?: string @grafanamaturity(NeedsExpertReview)
|
||||
|
||||
|
||||
@@ -15,6 +15,13 @@ export type {
|
||||
DashboardLink,
|
||||
DashboardLinkType,
|
||||
DashboardLinkPlacement,
|
||||
ActionType,
|
||||
FetchOptions,
|
||||
InfinityOptions,
|
||||
HttpRequestMethod,
|
||||
ActionVariableType,
|
||||
ActionVariable,
|
||||
Action,
|
||||
VariableType,
|
||||
FieldColorSeriesByMode,
|
||||
FieldColor,
|
||||
@@ -37,6 +44,9 @@ export {
|
||||
VariableRefresh,
|
||||
VariableSort,
|
||||
defaultDashboardLink,
|
||||
defaultFetchOptions,
|
||||
defaultInfinityOptions,
|
||||
defaultAction,
|
||||
FieldColorModeId,
|
||||
defaultGridPos,
|
||||
ThresholdsMode,
|
||||
|
||||
@@ -363,6 +363,87 @@ export type DashboardLinkType = ('link' | 'dashboards');
|
||||
*/
|
||||
export type DashboardLinkPlacement = 'inControlsMenu';
|
||||
|
||||
/**
|
||||
* Dashboard action type
|
||||
*/
|
||||
export type ActionType = ('fetch' | 'infinity');
|
||||
|
||||
/**
|
||||
* Fetch options
|
||||
*/
|
||||
export interface FetchOptions {
|
||||
body?: string;
|
||||
headers?: Array<Array<string>>;
|
||||
method: HttpRequestMethod;
|
||||
/**
|
||||
* These are 2D arrays of strings, each representing a key-value pair
|
||||
* We are defining this way because we can't generate a go struct that
|
||||
* that would have exactly two strings in each sub-array
|
||||
*/
|
||||
queryParams?: Array<Array<string>>;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export const defaultFetchOptions: Partial<FetchOptions> = {
|
||||
headers: [],
|
||||
queryParams: [],
|
||||
};
|
||||
|
||||
/**
|
||||
* Infinity options
|
||||
*/
|
||||
export interface InfinityOptions {
|
||||
body?: string;
|
||||
datasourceUid: string;
|
||||
headers?: Array<Array<string>>;
|
||||
method: HttpRequestMethod;
|
||||
/**
|
||||
* These are 2D arrays of strings, each representing a key-value pair
|
||||
* We are defining them this way because we can't generate a go struct that
|
||||
* that would have exactly two strings in each sub-array
|
||||
*/
|
||||
queryParams?: Array<Array<string>>;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export const defaultInfinityOptions: Partial<InfinityOptions> = {
|
||||
headers: [],
|
||||
queryParams: [],
|
||||
};
|
||||
|
||||
export type HttpRequestMethod = ('GET' | 'PUT' | 'POST' | 'DELETE' | 'PATCH');
|
||||
|
||||
/**
|
||||
* Action variable type
|
||||
*/
|
||||
export type ActionVariableType = 'string';
|
||||
|
||||
export interface ActionVariable {
|
||||
key: string;
|
||||
name: string;
|
||||
type: ActionVariableType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dashboard action
|
||||
*/
|
||||
export interface Action {
|
||||
confirmation?: string;
|
||||
fetch?: FetchOptions;
|
||||
infinity?: InfinityOptions;
|
||||
oneClick?: boolean;
|
||||
style?: {
|
||||
backgroundColor?: string;
|
||||
};
|
||||
title: string;
|
||||
type: ActionType;
|
||||
variables?: Array<ActionVariable>;
|
||||
}
|
||||
|
||||
export const defaultAction: Partial<Action> = {
|
||||
variables: [],
|
||||
};
|
||||
|
||||
/**
|
||||
* Dashboard variable type
|
||||
* `query`: Query-generated list of values such as metric names, server names, sensor IDs, data centers, and so on.
|
||||
@@ -916,6 +997,10 @@ export const defaultMatcherConfig: Partial<MatcherConfig> = {
|
||||
* Field options allow you to change how the data is displayed in your visualizations.
|
||||
*/
|
||||
export interface FieldConfig {
|
||||
/**
|
||||
* Define interactive HTTP requests that can be triggered from data visualizations.
|
||||
*/
|
||||
actions?: Array<Action>;
|
||||
/**
|
||||
* Panel color configuration
|
||||
*/
|
||||
@@ -1001,6 +1086,7 @@ export interface FieldConfig {
|
||||
}
|
||||
|
||||
export const defaultFieldConfig: Partial<FieldConfig> = {
|
||||
actions: [],
|
||||
links: [],
|
||||
mappings: [],
|
||||
};
|
||||
|
||||
@@ -318,6 +318,8 @@ export interface FieldConfig {
|
||||
color?: FieldColor;
|
||||
// The behavior when clicking on a result
|
||||
links?: any[];
|
||||
// Define interactive HTTP requests that can be triggered from data visualizations.
|
||||
actions?: Action[];
|
||||
// Alternative to empty string
|
||||
noValue?: string;
|
||||
// custom is specified by the FieldConfig field
|
||||
@@ -505,6 +507,81 @@ export type FieldColorSeriesByMode = "min" | "max" | "last";
|
||||
|
||||
export const defaultFieldColorSeriesByMode = (): FieldColorSeriesByMode => ("min");
|
||||
|
||||
export interface Action {
|
||||
type: ActionType;
|
||||
title: string;
|
||||
fetch?: FetchOptions;
|
||||
infinity?: InfinityOptions;
|
||||
confirmation?: string;
|
||||
oneClick?: boolean;
|
||||
variables?: ActionVariable[];
|
||||
style?: {
|
||||
backgroundColor?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export const defaultAction = (): Action => ({
|
||||
type: "fetch",
|
||||
title: "",
|
||||
});
|
||||
|
||||
export type ActionType = "fetch" | "infinity";
|
||||
|
||||
export const defaultActionType = (): ActionType => ("fetch");
|
||||
|
||||
export interface FetchOptions {
|
||||
method: HttpRequestMethod;
|
||||
url: string;
|
||||
body?: string;
|
||||
// These are 2D arrays of strings, each representing a key-value pair
|
||||
// We are defining them this way because we can't generate a go struct that
|
||||
// that would have exactly two strings in each sub-array
|
||||
queryParams?: string[][];
|
||||
headers?: string[][];
|
||||
}
|
||||
|
||||
export const defaultFetchOptions = (): FetchOptions => ({
|
||||
method: "GET",
|
||||
url: "",
|
||||
});
|
||||
|
||||
export type HttpRequestMethod = "GET" | "PUT" | "POST" | "DELETE" | "PATCH";
|
||||
|
||||
export const defaultHttpRequestMethod = (): HttpRequestMethod => ("GET");
|
||||
|
||||
export interface InfinityOptions {
|
||||
method: HttpRequestMethod;
|
||||
url: string;
|
||||
body?: string;
|
||||
// These are 2D arrays of strings, each representing a key-value pair
|
||||
// We are defining them this way because we can't generate a go struct that
|
||||
// that would have exactly two strings in each sub-array
|
||||
queryParams?: string[][];
|
||||
datasourceUid: string;
|
||||
headers?: string[][];
|
||||
}
|
||||
|
||||
export const defaultInfinityOptions = (): InfinityOptions => ({
|
||||
method: "GET",
|
||||
url: "",
|
||||
datasourceUid: "",
|
||||
});
|
||||
|
||||
export interface ActionVariable {
|
||||
key: string;
|
||||
name: string;
|
||||
type: "string";
|
||||
}
|
||||
|
||||
export const defaultActionVariable = (): ActionVariable => ({
|
||||
key: "",
|
||||
name: "",
|
||||
type: ActionVariableType,
|
||||
});
|
||||
|
||||
// Action variable type
|
||||
export const ActionVariableType = "string";
|
||||
|
||||
export interface DynamicConfigValue {
|
||||
id: string;
|
||||
value?: any;
|
||||
|
||||
@@ -317,6 +317,8 @@ export interface FieldConfig {
|
||||
color?: FieldColor;
|
||||
// The behavior when clicking on a result
|
||||
links?: any[];
|
||||
// Define interactive HTTP requests that can be triggered from data visualizations.
|
||||
actions?: Action[];
|
||||
// Alternative to empty string
|
||||
noValue?: string;
|
||||
// custom is specified by the FieldConfig field
|
||||
@@ -504,6 +506,81 @@ export type FieldColorSeriesByMode = "min" | "max" | "last";
|
||||
|
||||
export const defaultFieldColorSeriesByMode = (): FieldColorSeriesByMode => ("min");
|
||||
|
||||
export interface Action {
|
||||
type: ActionType;
|
||||
title: string;
|
||||
fetch?: FetchOptions;
|
||||
infinity?: InfinityOptions;
|
||||
confirmation?: string;
|
||||
oneClick?: boolean;
|
||||
variables?: ActionVariable[];
|
||||
style?: {
|
||||
backgroundColor?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export const defaultAction = (): Action => ({
|
||||
type: "fetch",
|
||||
title: "",
|
||||
});
|
||||
|
||||
export type ActionType = "fetch" | "infinity";
|
||||
|
||||
export const defaultActionType = (): ActionType => ("fetch");
|
||||
|
||||
export interface FetchOptions {
|
||||
method: HttpRequestMethod;
|
||||
url: string;
|
||||
body?: string;
|
||||
// These are 2D arrays of strings, each representing a key-value pair
|
||||
// We are defining them this way because we can't generate a go struct that
|
||||
// that would have exactly two strings in each sub-array
|
||||
queryParams?: string[][];
|
||||
headers?: string[][];
|
||||
}
|
||||
|
||||
export const defaultFetchOptions = (): FetchOptions => ({
|
||||
method: "GET",
|
||||
url: "",
|
||||
});
|
||||
|
||||
export type HttpRequestMethod = "GET" | "PUT" | "POST" | "DELETE" | "PATCH";
|
||||
|
||||
export const defaultHttpRequestMethod = (): HttpRequestMethod => ("GET");
|
||||
|
||||
export interface InfinityOptions {
|
||||
method: HttpRequestMethod;
|
||||
url: string;
|
||||
body?: string;
|
||||
// These are 2D arrays of strings, each representing a key-value pair
|
||||
// We are defining them this way because we can't generate a go struct that
|
||||
// that would have exactly two strings in each sub-array
|
||||
queryParams?: string[][];
|
||||
datasourceUid: string;
|
||||
headers?: string[][];
|
||||
}
|
||||
|
||||
export const defaultInfinityOptions = (): InfinityOptions => ({
|
||||
method: "GET",
|
||||
url: "",
|
||||
datasourceUid: "",
|
||||
});
|
||||
|
||||
export interface ActionVariable {
|
||||
key: string;
|
||||
name: string;
|
||||
type: "string";
|
||||
}
|
||||
|
||||
export const defaultActionVariable = (): ActionVariable => ({
|
||||
key: "",
|
||||
name: "",
|
||||
type: ActionVariableType,
|
||||
});
|
||||
|
||||
// Action variable type
|
||||
export const ActionVariableType = "string";
|
||||
|
||||
export interface DynamicConfigValue {
|
||||
id: string;
|
||||
value?: any;
|
||||
|
||||
@@ -427,6 +427,8 @@ type FieldConfig struct {
|
||||
Color *FieldColor `json:"color,omitempty"`
|
||||
// The behavior when clicking on a result
|
||||
Links []any `json:"links,omitempty"`
|
||||
// Define interactive HTTP requests that can be triggered from data visualizations.
|
||||
Actions []Action `json:"actions,omitempty"`
|
||||
// Alternative to empty string
|
||||
NoValue *string `json:"noValue,omitempty"`
|
||||
// custom is specified by the FieldConfig field
|
||||
@@ -654,6 +656,92 @@ const (
|
||||
FieldColorSeriesByModeLast FieldColorSeriesByMode = "last"
|
||||
)
|
||||
|
||||
// Dashboard action
|
||||
type Action struct {
|
||||
Type ActionType `json:"type"`
|
||||
Title string `json:"title"`
|
||||
Fetch *FetchOptions `json:"fetch,omitempty"`
|
||||
Infinity *InfinityOptions `json:"infinity,omitempty"`
|
||||
Confirmation *string `json:"confirmation,omitempty"`
|
||||
OneClick *bool `json:"oneClick,omitempty"`
|
||||
Variables []ActionVariable `json:"variables,omitempty"`
|
||||
Style *DashboardActionStyle `json:"style,omitempty"`
|
||||
}
|
||||
|
||||
// NewAction creates a new Action object.
|
||||
func NewAction() *Action {
|
||||
return &Action{}
|
||||
}
|
||||
|
||||
// Dashboard action type
|
||||
type ActionType string
|
||||
|
||||
const (
|
||||
ActionTypeFetch ActionType = "fetch"
|
||||
ActionTypeInfinity ActionType = "infinity"
|
||||
)
|
||||
|
||||
// Fetch options
|
||||
type FetchOptions struct {
|
||||
Method HttpRequestMethod `json:"method"`
|
||||
Url string `json:"url"`
|
||||
Body *string `json:"body,omitempty"`
|
||||
// These are 2D arrays of strings, each representing a key-value pair
|
||||
// We are defining this way because we can't generate a go struct that
|
||||
// that would have exactly two strings in each sub-array
|
||||
QueryParams [][]string `json:"queryParams,omitempty"`
|
||||
Headers [][]string `json:"headers,omitempty"`
|
||||
}
|
||||
|
||||
// NewFetchOptions creates a new FetchOptions object.
|
||||
func NewFetchOptions() *FetchOptions {
|
||||
return &FetchOptions{}
|
||||
}
|
||||
|
||||
type HttpRequestMethod string
|
||||
|
||||
const (
|
||||
HttpRequestMethodGET HttpRequestMethod = "GET"
|
||||
HttpRequestMethodPUT HttpRequestMethod = "PUT"
|
||||
HttpRequestMethodPOST HttpRequestMethod = "POST"
|
||||
HttpRequestMethodDELETE HttpRequestMethod = "DELETE"
|
||||
HttpRequestMethodPATCH HttpRequestMethod = "PATCH"
|
||||
)
|
||||
|
||||
// Infinity options
|
||||
type InfinityOptions struct {
|
||||
Method HttpRequestMethod `json:"method"`
|
||||
Url string `json:"url"`
|
||||
Body *string `json:"body,omitempty"`
|
||||
// These are 2D arrays of strings, each representing a key-value pair
|
||||
// We are defining them this way because we can't generate a go struct that
|
||||
// that would have exactly two strings in each sub-array
|
||||
QueryParams [][]string `json:"queryParams,omitempty"`
|
||||
Headers [][]string `json:"headers,omitempty"`
|
||||
DatasourceUid string `json:"datasourceUid"`
|
||||
}
|
||||
|
||||
// NewInfinityOptions creates a new InfinityOptions object.
|
||||
func NewInfinityOptions() *InfinityOptions {
|
||||
return &InfinityOptions{}
|
||||
}
|
||||
|
||||
type ActionVariable struct {
|
||||
Key string `json:"key"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
// NewActionVariable creates a new ActionVariable object.
|
||||
func NewActionVariable() *ActionVariable {
|
||||
return &ActionVariable{
|
||||
Type: ActionVariableType,
|
||||
}
|
||||
}
|
||||
|
||||
// Action variable type
|
||||
const ActionVariableType = "string"
|
||||
|
||||
type DynamicConfigValue struct {
|
||||
Id string `json:"id"`
|
||||
Value any `json:"value,omitempty"`
|
||||
@@ -1042,6 +1130,15 @@ func NewDashboardSpecialValueMapOptions() *DashboardSpecialValueMapOptions {
|
||||
}
|
||||
}
|
||||
|
||||
type DashboardActionStyle struct {
|
||||
BackgroundColor *string `json:"backgroundColor,omitempty"`
|
||||
}
|
||||
|
||||
// NewDashboardActionStyle creates a new DashboardActionStyle object.
|
||||
func NewDashboardActionStyle() *DashboardActionStyle {
|
||||
return &DashboardActionStyle{}
|
||||
}
|
||||
|
||||
type PanelRepeatDirection string
|
||||
|
||||
const (
|
||||
|
||||
@@ -1060,6 +1060,71 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"com.github.grafana.grafana.apps.dashboard.pkg.apis.dashboard.v2alpha1.DashboardAction": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"type",
|
||||
"title"
|
||||
],
|
||||
"properties": {
|
||||
"confirmation": {
|
||||
"type": "string"
|
||||
},
|
||||
"fetch": {
|
||||
"$ref": "#/components/schemas/com.github.grafana.grafana.apps.dashboard.pkg.apis.dashboard.v2alpha1.DashboardFetchOptions"
|
||||
},
|
||||
"infinity": {
|
||||
"$ref": "#/components/schemas/com.github.grafana.grafana.apps.dashboard.pkg.apis.dashboard.v2alpha1.DashboardInfinityOptions"
|
||||
},
|
||||
"oneClick": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"style": {
|
||||
"$ref": "#/components/schemas/com.github.grafana.grafana.apps.dashboard.pkg.apis.dashboard.v2alpha1.DashboardV2alpha1ActionStyle"
|
||||
},
|
||||
"title": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"variables": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/com.github.grafana.grafana.apps.dashboard.pkg.apis.dashboard.v2alpha1.DashboardActionVariable"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"com.github.grafana.grafana.apps.dashboard.pkg.apis.dashboard.v2alpha1.DashboardActionVariable": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"key",
|
||||
"name",
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"com.github.grafana.grafana.apps.dashboard.pkg.apis.dashboard.v2alpha1.DashboardAdHocFilterWithLabels": {
|
||||
"description": "Define the AdHocFilterWithLabels type",
|
||||
"type": "object",
|
||||
@@ -2062,6 +2127,47 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"com.github.grafana.grafana.apps.dashboard.pkg.apis.dashboard.v2alpha1.DashboardFetchOptions": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"method",
|
||||
"url"
|
||||
],
|
||||
"properties": {
|
||||
"body": {
|
||||
"type": "string"
|
||||
},
|
||||
"headers": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"method": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"queryParams": {
|
||||
"description": "These are 2D arrays of strings, each representing a key-value pair We are defining them this way because we can't generate a go struct that that would have exactly two strings in each sub-array",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"com.github.grafana.grafana.apps.dashboard.pkg.apis.dashboard.v2alpha1.DashboardFieldColor": {
|
||||
"description": "Map a field to a color.",
|
||||
"type": "object",
|
||||
@@ -2088,6 +2194,18 @@
|
||||
"description": "The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results. Each column within this structure is called a field. A field can represent a single time series or table column. Field options allow you to change how the data is displayed in your visualizations.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"actions": {
|
||||
"description": "Define interactive HTTP requests that can be triggered from data visualizations.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/com.github.grafana.grafana.apps.dashboard.pkg.apis.dashboard.v2alpha1.DashboardAction"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"color": {
|
||||
"description": "Panel color configuration",
|
||||
"allOf": [
|
||||
@@ -2427,6 +2545,52 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"com.github.grafana.grafana.apps.dashboard.pkg.apis.dashboard.v2alpha1.DashboardInfinityOptions": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"method",
|
||||
"url",
|
||||
"datasourceUid"
|
||||
],
|
||||
"properties": {
|
||||
"body": {
|
||||
"type": "string"
|
||||
},
|
||||
"datasourceUid": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"headers": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"method": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"queryParams": {
|
||||
"description": "These are 2D arrays of strings, each representing a key-value pair We are defining them this way because we can't generate a go struct that that would have exactly two strings in each sub-array",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"com.github.grafana.grafana.apps.dashboard.pkg.apis.dashboard.v2alpha1.DashboardIntervalVariableKind": {
|
||||
"description": "Interval variable kind",
|
||||
"type": "object",
|
||||
@@ -3735,6 +3899,14 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"com.github.grafana.grafana.apps.dashboard.pkg.apis.dashboard.v2alpha1.DashboardV2alpha1ActionStyle": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"backgroundColor": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"com.github.grafana.grafana.apps.dashboard.pkg.apis.dashboard.v2alpha1.DashboardV2alpha1FieldConfigSourceOverrides": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
||||
@@ -21,33 +21,33 @@ describe('transformToV2TypesUtils', () => {
|
||||
expect(transformCursorSynctoEnum(undefined)).toBe(defaultDashboardCursorSync());
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('transformVariableRefreshToEnum', () => {
|
||||
it('should return the correct enum value for variable refresh', () => {
|
||||
expect(transformVariableRefreshToEnum(0)).toBe('never');
|
||||
expect(transformVariableRefreshToEnum(1)).toBe('onDashboardLoad');
|
||||
expect(transformVariableRefreshToEnum(2)).toBe('onTimeRangeChanged');
|
||||
expect(transformVariableRefreshToEnum(undefined)).toBe(defaultVariableRefresh());
|
||||
describe('transformVariableRefreshToEnum', () => {
|
||||
it('should return the correct enum value for variable refresh', () => {
|
||||
expect(transformVariableRefreshToEnum(0)).toBe('never');
|
||||
expect(transformVariableRefreshToEnum(1)).toBe('onDashboardLoad');
|
||||
expect(transformVariableRefreshToEnum(2)).toBe('onTimeRangeChanged');
|
||||
expect(transformVariableRefreshToEnum(undefined)).toBe(defaultVariableRefresh());
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('transformVariableHideToEnum', () => {
|
||||
it('should return the correct enum value for variable hide', () => {
|
||||
expect(transformVariableHideToEnum(0)).toBe('dontHide');
|
||||
expect(transformVariableHideToEnum(1)).toBe('hideLabel');
|
||||
expect(transformVariableHideToEnum(2)).toBe('hideVariable');
|
||||
expect(transformVariableHideToEnum(undefined)).toBe(defaultVariableHide());
|
||||
describe('transformVariableHideToEnum', () => {
|
||||
it('should return the correct enum value for variable hide', () => {
|
||||
expect(transformVariableHideToEnum(0)).toBe('dontHide');
|
||||
expect(transformVariableHideToEnum(1)).toBe('hideLabel');
|
||||
expect(transformVariableHideToEnum(2)).toBe('hideVariable');
|
||||
expect(transformVariableHideToEnum(undefined)).toBe(defaultVariableHide());
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('transformSortVariableToEnum', () => {
|
||||
it('should return the correct enum value for variable sort', () => {
|
||||
expect(transformSortVariableToEnum(0)).toBe('disabled');
|
||||
expect(transformSortVariableToEnum(1)).toBe('alphabeticalAsc');
|
||||
expect(transformSortVariableToEnum(2)).toBe('alphabeticalDesc');
|
||||
expect(transformSortVariableToEnum(3)).toBe('numericalAsc');
|
||||
expect(transformSortVariableToEnum(4)).toBe('numericalDesc');
|
||||
expect(transformSortVariableToEnum(undefined)).toBe(defaultVariableSort());
|
||||
describe('transformSortVariableToEnum', () => {
|
||||
it('should return the correct enum value for variable sort', () => {
|
||||
expect(transformSortVariableToEnum(0)).toBe('disabled');
|
||||
expect(transformSortVariableToEnum(1)).toBe('alphabeticalAsc');
|
||||
expect(transformSortVariableToEnum(2)).toBe('alphabeticalDesc');
|
||||
expect(transformSortVariableToEnum(3)).toBe('numericalAsc');
|
||||
expect(transformSortVariableToEnum(4)).toBe('numericalDesc');
|
||||
expect(transformSortVariableToEnum(undefined)).toBe(defaultVariableSort());
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user