├── .github
├── CODEOWNERS
├── dependabot.yml
├── workflows
│ ├── release.yml
│ └── test.yml
└── CODE_OF_CONDUCT.md
├── .gitmodules
├── terraform-registry-manifest.json
├── gen
├── README.md
├── internal
│ ├── tmpl
│ │ └── gen_header.tmpl
│ ├── tmpl.go
│ ├── jenny_major.go
│ ├── all.go
│ └── jenny_eachmajorcomposable.go
├── terraform
│ ├── terraform.go
│ ├── cuetf
│ │ ├── templates
│ │ │ ├── schema_attribute.tmpl
│ │ │ └── datasource.tmpl
│ │ ├── types
│ │ │ ├── mappings.go
│ │ │ ├── node.go
│ │ │ └── model.go
│ │ ├── internal
│ │ │ ├── utils
│ │ │ │ └── utils.go
│ │ │ └── nodes.go
│ │ ├── tmpl.go
│ │ └── datasource_generator.go
│ ├── jenny_datasource.go
│ └── jenny_datasource_registry.go
└── gen.go
├── tools
└── tools.go
├── CODEOWNERS
├── GNUmakefile
├── catalog-info.yaml
├── .golangci.yml
├── .gitignore
├── .vscode
└── launch.json
├── CHANGELOG.md
├── internal
└── provider
│ ├── provider_test.go
│ ├── registry_gen.go
│ ├── provider.go
│ ├── datasource_query_parca_gen.go
│ ├── datasource_query_grafana_pyroscope_gen.go
│ ├── datasource_query_loki_gen.go
│ └── datasource_query_prometheus_gen.go
├── docs
├── data-sources
│ ├── query_parca.md
│ ├── query_grafana_pyroscope.md
│ ├── query_loki.md
│ ├── query_prometheus.md
│ ├── query_test_data.md
│ ├── core_dashboard.md
│ ├── panel_alert_groups.md
│ ├── panel_annotations_list.md
│ └── panel_text.md
└── index.md
├── examples
└── schemas_core_dashboard
│ ├── simple
│ └── dashboard.tf
│ └── prometheus
│ └── dashboard.tf
├── main.go
├── .goreleaser.yml
├── templates
└── index.md.tmpl
├── README.md
├── go.mod
└── LICENSE
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @grafana/grafana-as-code
2 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "tools/grok"]
2 | path = tools/grok
3 | url = https://github.com/grafana/grok
4 |
--------------------------------------------------------------------------------
/terraform-registry-manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 1,
3 | "metadata": {
4 | "protocol_versions": ["6.0"]
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/gen/README.md:
--------------------------------------------------------------------------------
1 | This code should end in Grok and Thema but will stay here to ease the development workflow as this is still in an experimental state.
--------------------------------------------------------------------------------
/tools/tools.go:
--------------------------------------------------------------------------------
1 | //go:build tools
2 |
3 | package tools
4 |
5 | import (
6 | // Documentation generation
7 | _ "github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs"
8 | )
9 |
--------------------------------------------------------------------------------
/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # Docs on CODEOWNERS:
2 | # https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
3 | #
4 | # Later codeowner matches take precedence over earlier ones.
5 |
6 | # Default owner
7 | * @grafana/platform-cat
8 |
--------------------------------------------------------------------------------
/GNUmakefile:
--------------------------------------------------------------------------------
1 | default: testacc
2 |
3 | # Run acceptance tests
4 | .PHONY: testacc
5 | testacc:
6 | TF_ACC=1 go test ./... -v $(TESTARGS) -timeout 120m
7 |
8 | .PHONY: generate
9 | generate:
10 | rm -rf ./internal/provider/*_gen.go
11 | cd ./gen && MIN_MATURITY=merged go generate ./
12 | go generate ./
13 |
--------------------------------------------------------------------------------
/gen/internal/tmpl/gen_header.tmpl:
--------------------------------------------------------------------------------
1 | // Code generated - EDITING IS FUTILE. DO NOT EDIT.
2 | //
3 | // Generated by pipeline:
4 | // {{ .MainGenerator }}
5 | // Using jennies:
6 | {{- range .Using }}
7 | // {{ .JennyName }}
8 | {{- end }}
9 | //
10 | // Run 'go generate ./' from repository root to regenerate.
11 |
12 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # See GitHub's documentation for more information on this file:
2 | # https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/configuration-options-for-dependency-updates
3 | version: 2
4 | updates:
5 | - package-ecosystem: "github-actions"
6 | directory: "/"
7 | schedule:
8 | interval: "daily"
9 | - package-ecosystem: "gomod"
10 | directory: "/"
11 | schedule:
12 | interval: "daily"
13 |
--------------------------------------------------------------------------------
/gen/terraform/terraform.go:
--------------------------------------------------------------------------------
1 | package terraform
2 |
3 | import (
4 | jen "github.com/grafana/terraform-provider-schemas/gen/internal"
5 | )
6 |
7 | func JenniesForTerraform() jen.TargetJennies {
8 | tgt := jen.NewTargetJennies()
9 |
10 | tgt.Core.Append(
11 | jen.LatestJenny("", TerraformDataSourceJenny{}),
12 | &TerraformCoreRegistryJenny{},
13 | )
14 |
15 | tgt.Composable.Append(
16 | jen.ComposableLatestMajorsOrXJenny("", true, TerraformDataSourceJenny{}),
17 | &TerraformComposableRegistryJenny{},
18 | )
19 |
20 | return tgt
21 | }
22 |
--------------------------------------------------------------------------------
/catalog-info.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: backstage.io/v1alpha1
2 | kind: Component
3 | metadata:
4 | name: terraform-provider-schemas
5 | title: Grafana Schemas Terraform Provider
6 | annotations:
7 | github.com/project-slug: grafana/terraform-provider-schemas
8 | links:
9 | - title: Slack Channel
10 | url: https://raintank-corp.slack.com/archives/C018SLDD5MW
11 | description: |
12 | Generated Terraform provider to manage Grafana dashboards
13 | spec:
14 | type: library
15 | owner: group:default/platform-monitoring
16 | lifecycle: experimental
17 |
--------------------------------------------------------------------------------
/.golangci.yml:
--------------------------------------------------------------------------------
1 | # Visit https://golangci-lint.run/ for usage documentation
2 | # and information on other useful linters
3 | run:
4 | timeout: 2m
5 |
6 | issues:
7 | max-per-linter: 0
8 | max-same-issues: 0
9 |
10 | linters:
11 | disable-all: true
12 | enable:
13 | - durationcheck
14 | - errcheck
15 | - exportloopref
16 | - forcetypeassert
17 | - godot
18 | - gofmt
19 | - gosimple
20 | - ineffassign
21 | - makezero
22 | - misspell
23 | - nilerr
24 | - predeclared
25 | - staticcheck
26 | - tenv
27 | - unconvert
28 | - unparam
29 | - unused
30 | - vet
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.dll
2 | *.exe
3 | .DS_Store
4 | example.tf
5 | terraform.tfplan
6 | terraform.tfstate
7 | .terraform.lock.hcl
8 | bin/
9 | dist/
10 | modules-dev/
11 | /pkg/
12 | website/.vagrant
13 | website/.bundle
14 | website/build
15 | website/node_modules
16 | .vagrant/
17 | *.backup
18 | ./*.tfstate
19 | .terraform/
20 | *.log
21 | *.bak
22 | *~
23 | .*.swp
24 | .idea
25 | *.iml
26 | *.test
27 | *.iml
28 |
29 | website/vendor
30 |
31 | # Test exclusions
32 | !command/test-fixtures/**/*.tfstate
33 | !command/test-fixtures/**/.terraform/
34 |
35 | # Keep windows files with windows line endings
36 | *.winfile eol=crlf
37 |
38 | terraform-provider-schemas
39 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | "name": "Run provider",
6 | "type": "go",
7 | "request": "launch",
8 | "mode": "auto",
9 | "program": "${workspaceFolder}/main.go",
10 | "args": ["--debug"],
11 | },
12 | {
13 | "name": "Run generate",
14 | "type": "go",
15 | "request": "launch",
16 | "mode": "auto",
17 | "program": "${workspaceFolder}/gen/gen.go",
18 | "env": {
19 | "MIN_MATURITY": "merged",
20 | },
21 | "cwd": "${workspaceFolder}"
22 | },
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 0.1.0
2 |
3 | Provides data sources to help build a dashboard JSON object.
4 | Contains a data source for the dashboard object and for the following plugins:
5 |
6 | *Panels:*
7 | - Alert groups
8 | - Annotations list
9 | - Bar chart
10 | - Bar gauge
11 | - Dashboard list
12 | - Data grid
13 | - Debug
14 | - Gauge
15 | - Geomap
16 | - Heatmap
17 | - Histogram
18 | - Logs
19 | - News
20 | - Node graph
21 | - Pie chart
22 | - Stat
23 | - State timeline
24 | - Table
25 | - Text
26 | - Time series
27 | - Trend
28 | - XY chart
29 |
30 | *Data sources:*
31 | - Elasticsearch
32 | - Pyroscope
33 | - Loki
34 | - Parca
35 | - Prometheus
36 | - Testdata
37 |
--------------------------------------------------------------------------------
/gen/terraform/cuetf/templates/schema_attribute.tmpl:
--------------------------------------------------------------------------------
1 | "{{.Name}}": schema.{{.AttributeType}}Attribute{
2 | MarkdownDescription: `{{.Description}}`,
3 | Computed: {{.Computed}},
4 | Optional: {{.Optional}},
5 | Required: {{not .Optional}},
6 | {{ if .ElementType }}ElementType: {{.ElementType}},{{ end }}
7 | {{- if .DeprecationMessage }}DeprecationMessage: `{{.DeprecationMessage}}`,{{ end }}
8 | {{- if .NestedAttributes }}Attributes: map[string]schema.Attribute{
9 | {{.NestedAttributes}}
10 | },{{ end }}
11 | {{- if .NestedObjectAttributes }}NestedObject: schema.NestedAttributeObject{
12 | Attributes: map[string]schema.Attribute{
13 | {{.NestedObjectAttributes}}
14 | },
15 | },{{ end }}
16 | },
17 |
--------------------------------------------------------------------------------
/internal/provider/provider_test.go:
--------------------------------------------------------------------------------
1 | package provider
2 |
3 | // testAccProtoV6ProviderFactories are used to instantiate a provider during
4 | // acceptance testing. The factory function will be invoked for every Terraform
5 | // CLI command executed to create a provider server to which the CLI can
6 | // reattach.
7 | // var testAccProtoV6ProviderFactories = map[string]func() (tfprotov6.ProviderServer, error){
8 | // "schemas": providerserver.NewProtocol6WithError(New("schemas")()),
9 | // }
10 |
11 | // func testAccPreCheck(t *testing.T) {
12 | // // You can add code here to run prior to any test case execution, for example assertions
13 | // // about the appropriate environment variables being set are common to see in a pre-check
14 | // // function.
15 | // }
16 |
--------------------------------------------------------------------------------
/gen/internal/tmpl.go:
--------------------------------------------------------------------------------
1 | package jen
2 |
3 | import (
4 | "embed"
5 | "text/template"
6 | "time"
7 |
8 | "github.com/grafana/codejen"
9 | )
10 |
11 | // All the parsed templates in the tmpl subdirectory.
12 | var tmpls *template.Template
13 |
14 | func init() {
15 | base := template.New("codegen").Funcs(template.FuncMap{
16 | "now": time.Now,
17 | })
18 | tmpls = template.Must(base.ParseFS(tmplFS, "tmpl/*.tmpl"))
19 | }
20 |
21 | //go:embed tmpl/*.tmpl
22 | var tmplFS embed.FS
23 |
24 | // The following group of types, beginning with tvars_*, all contain the set
25 | // of variables expected by the corresponding named template file under "tmpl/".
26 | type (
27 | tvars_gen_header struct {
28 | MainGenerator string
29 | Using []codejen.NamedJenny
30 | From string
31 | }
32 | )
33 |
--------------------------------------------------------------------------------
/gen/terraform/cuetf/types/mappings.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import "cuelang.org/go/cue"
4 |
5 | type kindMapping struct {
6 | terraformType string
7 | golangType string
8 | terraformFunc string
9 | }
10 |
11 | var kindMappings = map[cue.Kind]*kindMapping{
12 | cue.BoolKind: {
13 | terraformType: "Bool",
14 | golangType: "bool",
15 | terraformFunc: "ValueBool",
16 | },
17 | cue.IntKind: {
18 | terraformType: "Int64",
19 | golangType: "int64",
20 | terraformFunc: "ValueInt64",
21 | },
22 | cue.FloatKind: {
23 | terraformType: "Float64",
24 | golangType: "float64",
25 | terraformFunc: "ValueFloat64",
26 | },
27 | cue.NumberKind: {
28 | terraformType: "Float64",
29 | golangType: "float64",
30 | terraformFunc: "ValueFloat64",
31 | },
32 | cue.StringKind: {
33 | terraformType: "String",
34 | golangType: "string",
35 | terraformFunc: "ValueString",
36 | },
37 | }
38 |
--------------------------------------------------------------------------------
/gen/terraform/jenny_datasource.go:
--------------------------------------------------------------------------------
1 | package terraform
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/grafana/codejen"
7 | "github.com/grafana/grafana/pkg/codegen"
8 | "github.com/grafana/terraform-provider-schemas/gen/terraform/cuetf"
9 | "golang.org/x/tools/imports"
10 | )
11 |
12 | type TerraformDataSourceJenny struct{}
13 |
14 | func (j TerraformDataSourceJenny) JennyName() string {
15 | return "TerraformDataSourceJenny"
16 | }
17 |
18 | func (j TerraformDataSourceJenny) Generate(sfg codegen.SchemaForGen) (*codejen.File, error) {
19 | bytes, err := cuetf.GenerateDataSource(sfg.Schema)
20 | if err != nil {
21 | return nil, err
22 | }
23 |
24 | name := cuetf.GetResourceName(sfg.Schema.Lineage().Name())
25 | fname := "datasource_" + name + "_gen.go"
26 |
27 | bytes, err = imports.Process(fname, bytes, nil)
28 | if err != nil {
29 | return nil, fmt.Errorf("goimports processing of generated file failed: %w", err)
30 | }
31 |
32 | return codejen.NewFile(fname, bytes, j), nil
33 | }
34 |
--------------------------------------------------------------------------------
/gen/terraform/cuetf/internal/utils/utils.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | "regexp"
5 | "strings"
6 |
7 | "golang.org/x/text/cases"
8 | "golang.org/x/text/language"
9 | )
10 |
11 | var matchFirstCap = regexp.MustCompile("(.)([A-Z][a-z]+)")
12 | var matchAllCap = regexp.MustCompile("([a-z0-9])([A-Z])")
13 |
14 | func Title(str string) string {
15 | var caser = cases.Title(language.English, cases.NoLower)
16 | return caser.String(str)
17 | }
18 |
19 | func ToSnakeCase(str string) string {
20 | snake := matchFirstCap.ReplaceAllString(str, "${1}_${2}")
21 | snake = matchAllCap.ReplaceAllString(snake, "${1}_${2}")
22 | return strings.ToLower(snake)
23 | }
24 |
25 | func ToCamelCase(str string) string {
26 | words := strings.Split(str, "_")
27 | camelCase := ""
28 | for _, s := range words {
29 | camelCase += Title(s)
30 | }
31 | return camelCase
32 | }
33 |
34 | func CapitalizeFirstLetter(str string) string {
35 | sep := " "
36 | parts := strings.SplitN(str, sep, 2)
37 | if len(parts) != 2 {
38 | return Title(str)
39 | }
40 | return Title(parts[0]) + sep + parts[1]
41 | }
42 |
--------------------------------------------------------------------------------
/docs/data-sources/query_parca.md:
--------------------------------------------------------------------------------
1 | ---
2 | # generated by https://github.com/hashicorp/terraform-plugin-docs
3 | page_title: "schemas_query_parca Data Source - terraform-provider-schemas"
4 | subcategory: ""
5 | description: |-
6 |
7 | ---
8 |
9 | # schemas_query_parca (Data Source)
10 |
11 |
12 |
13 |
14 |
15 |
16 | ## Schema
17 |
18 | ### Required
19 |
20 | - `profile_type_id` (String) Specifies the type of profile to query.
21 | - `ref_id` (String) A unique identifier for the query within the list of targets.
22 | In server side expressions, the refId is used as a variable name to identify results.
23 | By default, the UI will assign A->Z; however setting meaningful names may be useful.
24 |
25 | ### Optional
26 |
27 | - `hide` (Boolean) true if query is disabled (ie should not be returned to the dashboard)
28 | Note this does not always imply that the query should not be executed since
29 | the results from a hidden query may be used as the input to other queries (SSE etc)
30 | - `label_selector` (String) Specifies the query label selectors. Defaults to "{}".
31 | - `query_type` (String) Specify the query flavor
32 | TODO make this required and give it a default
33 |
34 | ### Read-Only
35 |
36 | - `rendered_json` (String) This datasource rendered as JSON
37 |
--------------------------------------------------------------------------------
/gen/terraform/cuetf/tmpl.go:
--------------------------------------------------------------------------------
1 | package cuetf
2 |
3 | import (
4 | "embed"
5 | "strings"
6 | "text/template"
7 | )
8 |
9 | // All the parsed templates in the tmpl subdirectory.
10 | var tmpls *template.Template
11 |
12 | func init() {
13 | base := template.New("cuetf").Funcs(template.FuncMap{
14 | "lowerCase": strings.ToLower,
15 | "startsWith": strings.HasPrefix,
16 | })
17 | tmpls = template.Must(base.ParseFS(tmplFS, "templates/*.tmpl"))
18 | }
19 |
20 | //go:embed templates/*.tmpl
21 | var tmplFS embed.FS
22 |
23 | // The following group of types, beginning with tvars_*, all contain the set
24 | // of variables expected by the corresponding named template file under "templates/".
25 | type (
26 | TVarsDataSource struct {
27 | Name string
28 | StructName string
29 | Description string
30 | Models string
31 | SchemaAttributes string
32 | }
33 |
34 | TVarsSchemaAttribute struct {
35 | Name string
36 | Description string
37 | AttributeType string
38 | DeprecationMessage string
39 | Computed bool
40 | Optional bool
41 | ElementType string // Used for simple lists
42 | NestedAttributes string // Used for objects
43 | NestedObjectAttributes string // Used for complex lists
44 | }
45 | )
46 |
--------------------------------------------------------------------------------
/docs/data-sources/query_grafana_pyroscope.md:
--------------------------------------------------------------------------------
1 | ---
2 | # generated by https://github.com/hashicorp/terraform-plugin-docs
3 | page_title: "schemas_query_grafana_pyroscope Data Source - terraform-provider-schemas"
4 | subcategory: ""
5 | description: |-
6 |
7 | ---
8 |
9 | # schemas_query_grafana_pyroscope (Data Source)
10 |
11 |
12 |
13 |
14 |
15 |
16 | ## Schema
17 |
18 | ### Required
19 |
20 | - `profile_type_id` (String) Specifies the type of profile to query.
21 | - `ref_id` (String) A unique identifier for the query within the list of targets.
22 | In server side expressions, the refId is used as a variable name to identify results.
23 | By default, the UI will assign A->Z; however setting meaningful names may be useful.
24 |
25 | ### Optional
26 |
27 | - `group_by` (List of String) Allows to group the results.
28 | - `hide` (Boolean) true if query is disabled (ie should not be returned to the dashboard)
29 | Note this does not always imply that the query should not be executed since
30 | the results from a hidden query may be used as the input to other queries (SSE etc)
31 | - `label_selector` (String) Specifies the query label selectors. Defaults to "{}".
32 | - `max_nodes` (Number) Sets the maximum number of nodes in the flamegraph.
33 | - `query_type` (String) Specify the query flavor
34 | TODO make this required and give it a default
35 |
36 | ### Read-Only
37 |
38 | - `rendered_json` (String) This datasource rendered as JSON
39 |
--------------------------------------------------------------------------------
/examples/schemas_core_dashboard/simple/dashboard.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_providers {
3 | schemas = {
4 | source = "grafana/schemas"
5 | version = "0.1.0"
6 | }
7 | grafana = {
8 | source = "grafana/grafana"
9 | version = "1.36.1"
10 | }
11 | }
12 | }
13 |
14 | provider "grafana" {
15 | url = "http://localhost:3000"
16 | auth = "admin:admin"
17 | }
18 |
19 | resource "grafana_dashboard" "example" {
20 | config_json = data.schemas_core_dashboard.dashboard.rendered_json
21 | }
22 |
23 | data "schemas_core_dashboard" "dashboard" {
24 | title = "Faro dashboard"
25 | uid = "faro-terraform-demo"
26 | description = "Dashboard for Faro"
27 | graph_tooltip = 1
28 |
29 | panels = [
30 | data.schemas_panel_time_series.requests.rendered_json,
31 | ]
32 | }
33 |
34 | data "schemas_panel_time_series" "requests" {
35 | title = "Requests / sec"
36 |
37 | datasource = {
38 | uid = "ops-cortex"
39 | type = "prometheus"
40 | }
41 |
42 | targets = [
43 | data.schemas_query_prometheus.requests_target.rendered_json
44 | ]
45 |
46 | field_config = {
47 | defaults = {
48 | unit = "reqps"
49 | }
50 | }
51 |
52 | grid_pos = {
53 | h = 8
54 | w = 24
55 | }
56 | }
57 |
58 | data "schemas_query_prometheus" "requests_target" {
59 | expr = "sum by (status_code) (rate(request_duration_seconds_count{job=~\".*/faro-api\"}[$__rate_interval]))"
60 | format = "time_series"
61 | ref_id = "A"
62 | }
63 |
--------------------------------------------------------------------------------
/internal/provider/registry_gen.go:
--------------------------------------------------------------------------------
1 | // Code generated - EDITING IS FUTILE. DO NOT EDIT.
2 | //
3 | // Generated by pipeline:
4 | // terraform
5 | // Using jennies:
6 | // TerraformComposableRegistryJenny
7 | //
8 | // Run 'go generate ./' from repository root to regenerate.
9 |
10 | package provider
11 |
12 | import (
13 | "github.com/hashicorp/terraform-plugin-framework/datasource"
14 | )
15 |
16 | var datasources = []func() datasource.DataSource{
17 | NewCoreDashboardDataSource,
18 | NewQueryElasticsearchDataSource,
19 | NewQueryGrafanaPyroscopeDataSource,
20 | NewQueryLokiDataSource,
21 | NewQueryParcaDataSource,
22 | NewQueryPrometheusDataSource,
23 | NewQueryTestDataDataSource,
24 | NewPanelAlertGroupsDataSource,
25 | NewPanelAnnotationsListDataSource,
26 | NewPanelBarChartDataSource,
27 | NewPanelBarGaugeDataSource,
28 | NewPanelCandlestickDataSource,
29 | NewPanelCanvasDataSource,
30 | NewPanelDashboardListDataSource,
31 | NewPanelDatagridDataSource,
32 | NewPanelDebugDataSource,
33 | NewPanelGaugeDataSource,
34 | NewPanelGeomapDataSource,
35 | NewPanelHeatmapDataSource,
36 | NewPanelHistogramDataSource,
37 | NewPanelLogsDataSource,
38 | NewPanelNewsDataSource,
39 | NewPanelNodeGraphDataSource,
40 | NewPanelPieChartDataSource,
41 | NewPanelStatDataSource,
42 | NewPanelStateTimelineDataSource,
43 | NewPanelStatusHistoryDataSource,
44 | NewPanelTableDataSource,
45 | NewPanelTextDataSource,
46 | NewPanelTimeSeriesDataSource,
47 | NewPanelTrendDataSource,
48 | NewPanelXYChartDataSource,
49 | }
50 |
--------------------------------------------------------------------------------
/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "flag"
6 | "log"
7 |
8 | "github.com/grafana/terraform-provider-schemas/internal/provider"
9 | "github.com/hashicorp/terraform-plugin-framework/providerserver"
10 | )
11 |
12 | // Run "go generate" to format example terraform files and generate the docs for the registry/website.
13 |
14 | // If you do not have terraform installed, you can remove the formatting command, but its suggested to
15 | // ensure the documentation is formatted properly.
16 | //go:generate terraform fmt -recursive ./examples/
17 |
18 | // Run the docs generation tool, check its repository for more information on how it works and how docs
19 | // can be customized.
20 | //go:generate go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs
21 |
22 | var (
23 | // these will be set by the goreleaser configuration
24 | // to appropriate values for the compiled binary.
25 | version string = "dev"
26 |
27 | // goreleaser can pass other information to the main package, such as the specific commit
28 | // https://goreleaser.com/cookbooks/using-main.version/
29 | )
30 |
31 | func main() {
32 | var debug bool
33 |
34 | flag.BoolVar(&debug, "debug", false, "set to true to run the provider with support for debuggers like delve")
35 | flag.Parse()
36 |
37 | opts := providerserver.ServeOpts{
38 | Address: "registry.terraform.io/grafana/schemas",
39 | Debug: debug,
40 | }
41 |
42 | err := providerserver.Serve(context.Background(), provider.New(version), opts)
43 |
44 | if err != nil {
45 | log.Fatal(err.Error())
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/docs/data-sources/query_loki.md:
--------------------------------------------------------------------------------
1 | ---
2 | # generated by https://github.com/hashicorp/terraform-plugin-docs
3 | page_title: "schemas_query_loki Data Source - terraform-provider-schemas"
4 | subcategory: ""
5 | description: |-
6 |
7 | ---
8 |
9 | # schemas_query_loki (Data Source)
10 |
11 |
12 |
13 |
14 |
15 |
16 | ## Schema
17 |
18 | ### Required
19 |
20 | - `expr` (String) The LogQL query.
21 | - `ref_id` (String) A unique identifier for the query within the list of targets.
22 | In server side expressions, the refId is used as a variable name to identify results.
23 | By default, the UI will assign A->Z; however setting meaningful names may be useful.
24 |
25 | ### Optional
26 |
27 | - `editor_mode` (String)
28 | - `hide` (Boolean) true if query is disabled (ie should not be returned to the dashboard)
29 | Note this does not always imply that the query should not be executed since
30 | the results from a hidden query may be used as the input to other queries (SSE etc)
31 | - `instant` (Boolean, Deprecated) @deprecated, now use queryType.
32 | - `legend_format` (String) Used to override the name of the series.
33 | - `max_lines` (Number) Used to limit the number of log rows returned.
34 | - `query_type` (String) Specify the query flavor
35 | TODO make this required and give it a default
36 | - `range` (Boolean, Deprecated) @deprecated, now use queryType.
37 | - `resolution` (Number, Deprecated) @deprecated, now use step.
38 | - `step` (String) Used to set step value for range queries.
39 |
40 | ### Read-Only
41 |
42 | - `rendered_json` (String) This datasource rendered as JSON
43 |
--------------------------------------------------------------------------------
/gen/internal/jenny_major.go:
--------------------------------------------------------------------------------
1 | package jen
2 |
3 | import (
4 | "fmt"
5 | "path/filepath"
6 |
7 | "github.com/grafana/codejen"
8 | "github.com/grafana/grafana/pkg/codegen"
9 | "github.com/grafana/kindsys"
10 | )
11 |
12 | // LatestJenny returns a jenny that runs another jenny for only the latest
13 | // schema in a DefForGen, and prefixes the resulting file with the provided
14 | // parentdir (e.g. "pkg/kinds/").
15 | // TODO remove this once there's a standard jenny for this...somewhere in core.
16 | func LatestJenny(parentdir string, inner codejen.OneToOne[codegen.SchemaForGen]) codegen.OneToOne {
17 | if inner == nil {
18 | panic("inner jenny must not be nil")
19 | }
20 |
21 | return &latestj{
22 | parentdir: parentdir,
23 | inner: inner,
24 | }
25 | }
26 |
27 | type latestj struct {
28 | parentdir string
29 | inner codejen.OneToOne[codegen.SchemaForGen]
30 | }
31 |
32 | func (j *latestj) JennyName() string {
33 | return "LatestJenny"
34 | }
35 |
36 | func (j *latestj) Generate(kind kindsys.Kind) (*codejen.File, error) {
37 | comm := kind.Props().Common()
38 | sfg := codegen.SchemaForGen{
39 | Name: comm.Name,
40 | Schema: kind.Lineage().Latest(),
41 | IsGroup: comm.LineageIsGroup,
42 | }
43 |
44 | f, err := j.inner.Generate(sfg)
45 | if err != nil {
46 | return nil, fmt.Errorf("%s jenny failed on %s schema for %s: %w", j.inner.JennyName(), sfg.Schema.Version(), kind.Props().Common().Name, err)
47 | }
48 | if f == nil || !f.Exists() {
49 | return nil, nil
50 | }
51 |
52 | f.RelativePath = filepath.Join(j.parentdir, f.RelativePath)
53 | f.From = append(f.From, j)
54 | return f, nil
55 | }
56 |
--------------------------------------------------------------------------------
/gen/terraform/jenny_datasource_registry.go:
--------------------------------------------------------------------------------
1 | package terraform
2 |
3 | import (
4 | "fmt"
5 | "strings"
6 |
7 | "github.com/grafana/codejen"
8 | "github.com/grafana/kindsys"
9 | "github.com/grafana/terraform-provider-schemas/gen/terraform/cuetf"
10 | )
11 |
12 | var datasources []string
13 |
14 | type TerraformCoreRegistryJenny struct {
15 | }
16 |
17 | func (j TerraformCoreRegistryJenny) JennyName() string {
18 | return "TerraformCoreRegistryJenny"
19 | }
20 |
21 | func (j TerraformCoreRegistryJenny) Generate(k ...kindsys.Kind) (*codejen.File, error) {
22 | for _, k := range k {
23 | datasources = append(datasources, cuetf.GetStructName(k.Lineage().Name()))
24 | }
25 |
26 | return nil, nil
27 | }
28 |
29 | type TerraformComposableRegistryJenny struct {
30 | }
31 |
32 | func (j TerraformComposableRegistryJenny) JennyName() string {
33 | return "TerraformComposableRegistryJenny"
34 | }
35 |
36 | func (j TerraformComposableRegistryJenny) Generate(k ...kindsys.Composable) (*codejen.File, error) {
37 | for _, k := range k {
38 | datasources = append(datasources, cuetf.GetStructName(k.Lineage().Name()))
39 | }
40 |
41 | datasourceConstructors := []string{}
42 | for _, datasource := range datasources {
43 | datasourceConstructors = append(datasourceConstructors, "New"+datasource)
44 | }
45 |
46 | bytes := []byte(fmt.Sprintf(`package provider
47 |
48 | import (
49 | "github.com/hashicorp/terraform-plugin-framework/datasource"
50 | )
51 |
52 | var datasources = []func() datasource.DataSource{
53 | %s,
54 | }
55 | `, strings.Join(datasourceConstructors, ",\n ")))
56 |
57 | return codejen.NewFile("registry_gen.go", bytes, j), nil
58 | }
59 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | # Terraform Provider release workflow.
2 | name: Release
3 |
4 | # This GitHub action creates a release when a tag that matches the pattern
5 | # "v*" (e.g. v0.1.0) is created.
6 | on:
7 | push:
8 | tags:
9 | - 'v*'
10 |
11 | # Releases need permissions to read and write the repository contents.
12 | # GitHub considers creating releases and uploading assets as writing contents.
13 | permissions:
14 | contents: write
15 |
16 | jobs:
17 | goreleaser:
18 | runs-on: ubuntu-latest
19 | environment: release
20 | steps:
21 | - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
22 | with:
23 | # Allow goreleaser to access older tag information.
24 | fetch-depth: 0
25 | persist-credentials: false
26 | - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
27 | with:
28 | go-version-file: 'go.mod'
29 | # Disable cache to prevent cache poisoning attack
30 | cache: false
31 |
32 | - name: Import GPG key
33 | uses: crazy-max/ghaction-import-gpg@82a020f1f7f605c65dd2449b392a52c3fcfef7ef # v6.0.0
34 | id: import_gpg
35 | with:
36 | gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
37 | passphrase: ${{ secrets.PASSPHRASE }}
38 | - name: Run GoReleaser
39 | uses: goreleaser/goreleaser-action@7ec5c2b0c6cdda6e8bbb49444bc797dd33d74dd8 # v5.0.0
40 | with:
41 | args: release --clean
42 | env:
43 | # GitHub sets the GITHUB_TOKEN secret automatically.
44 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
45 | GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}
46 |
--------------------------------------------------------------------------------
/.goreleaser.yml:
--------------------------------------------------------------------------------
1 | # Visit https://goreleaser.com for documentation on how to customize this
2 | # behavior.
3 | before:
4 | hooks:
5 | # this is just an example and not a requirement for provider building/publishing
6 | - go mod tidy
7 | builds:
8 | - env:
9 | # goreleaser does not work with CGO, it could also complicate
10 | # usage by users in CI/CD systems like Terraform Cloud where
11 | # they are unable to install libraries.
12 | - CGO_ENABLED=0
13 | mod_timestamp: '{{ .CommitTimestamp }}'
14 | flags:
15 | - -trimpath
16 | ldflags:
17 | - '-s -w -X main.version={{.Version}} -X main.commit={{.Commit}}'
18 | goos:
19 | - freebsd
20 | - windows
21 | - linux
22 | - darwin
23 | goarch:
24 | - amd64
25 | - '386'
26 | - arm
27 | - arm64
28 | ignore:
29 | - goos: darwin
30 | goarch: '386'
31 | binary: '{{ .ProjectName }}_v{{ .Version }}'
32 | archives:
33 | - format: zip
34 | name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}'
35 | checksum:
36 | extra_files:
37 | - glob: 'terraform-registry-manifest.json'
38 | name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json'
39 | name_template: '{{ .ProjectName }}_{{ .Version }}_SHA256SUMS'
40 | algorithm: sha256
41 | signs:
42 | - artifacts: checksum
43 | args:
44 | # if you are using this in a GitHub action or some other automated pipeline, you
45 | # need to pass the batch flag to indicate its not interactive.
46 | - "--batch"
47 | - "--local-user"
48 | - "{{ .Env.GPG_FINGERPRINT }}" # set this environment variable for your signing key
49 | - "--output"
50 | - "${signature}"
51 | - "--detach-sign"
52 | - "${artifact}"
53 | release:
54 | extra_files:
55 | - glob: 'terraform-registry-manifest.json'
56 | name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json'
57 | # If you want to manually examine the release before its live, uncomment this line:
58 | # draft: true
59 | changelog:
60 | skip: true
61 |
--------------------------------------------------------------------------------
/docs/data-sources/query_prometheus.md:
--------------------------------------------------------------------------------
1 | ---
2 | # generated by https://github.com/hashicorp/terraform-plugin-docs
3 | page_title: "schemas_query_prometheus Data Source - terraform-provider-schemas"
4 | subcategory: ""
5 | description: |-
6 |
7 | ---
8 |
9 | # schemas_query_prometheus (Data Source)
10 |
11 |
12 |
13 |
14 |
15 |
16 | ## Schema
17 |
18 | ### Required
19 |
20 | - `expr` (String) The actual expression/query that will be evaluated by Prometheus
21 | - `ref_id` (String) A unique identifier for the query within the list of targets.
22 | In server side expressions, the refId is used as a variable name to identify results.
23 | By default, the UI will assign A->Z; however setting meaningful names may be useful.
24 |
25 | ### Optional
26 |
27 | - `editor_mode` (String) Specifies which editor is being used to prepare the query. It can be "code" or "builder"
28 | - `exemplar` (Boolean) Execute an additional query to identify interesting raw samples relevant for the given expr
29 | - `format` (String) Query format to determine how to display data points in panel. It can be "time_series", "table", "heatmap"
30 | - `hide` (Boolean) true if query is disabled (ie should not be returned to the dashboard)
31 | Note this does not always imply that the query should not be executed since
32 | the results from a hidden query may be used as the input to other queries (SSE etc)
33 | - `instant` (Boolean) Returns only the latest value that Prometheus has scraped for the requested time series
34 | - `interval_factor` (Number, Deprecated) @deprecated Used to specify how many times to divide max data points by. We use max data points under query options
35 | See https://github.com/grafana/grafana/issues/48081
36 | - `legend_format` (String) Series name override or template. Ex. {{hostname}} will be replaced with label value for hostname
37 | - `query_type` (String) Specify the query flavor
38 | TODO make this required and give it a default
39 | - `range` (Boolean) Returns a Range vector, comprised of a set of time series containing a range of data points over time for each time series
40 |
41 | ### Read-Only
42 |
43 | - `rendered_json` (String) This datasource rendered as JSON
44 |
--------------------------------------------------------------------------------
/gen/internal/all.go:
--------------------------------------------------------------------------------
1 | package jen
2 |
3 | import (
4 | "bytes"
5 | "fmt"
6 | "path/filepath"
7 |
8 | "github.com/grafana/codejen"
9 | "github.com/grafana/kindsys"
10 | )
11 |
12 | // TargetJennies is a set of jennies for a particular target language or
13 | // tool that perform all necessary code generation steps.
14 | type TargetJennies struct {
15 | Core *codejen.JennyList[kindsys.Kind]
16 | Composable *codejen.JennyList[kindsys.Composable]
17 | }
18 |
19 | // NewTargetJennies initializes a new TargetJennies with appropriate namers for
20 | // each JennyList.
21 | func NewTargetJennies() TargetJennies {
22 | return TargetJennies{
23 | Core: codejen.JennyListWithNamer[kindsys.Kind](func(k kindsys.Kind) string {
24 | return k.Props().Common().MachineName
25 | }),
26 | Composable: codejen.JennyListWithNamer[kindsys.Composable](func(k kindsys.Composable) string {
27 | return k.Name()
28 | }),
29 | }
30 | }
31 |
32 | // Prefixer returns a FileMapper that injects the provided path prefix to files
33 | // passed through it.
34 | func Prefixer(prefix string) codejen.FileMapper {
35 | return func(f codejen.File) (codejen.File, error) {
36 | f.RelativePath = filepath.Join(prefix, f.RelativePath)
37 | return f, nil
38 | }
39 | }
40 |
41 | // SlashHeaderMapper produces a FileMapper that injects a comment header onto
42 | // a [codejen.File] indicating the main generator that produced it (via the provided
43 | // maingen, which should be a path) and the jenny or jennies that constructed the
44 | // file.
45 | func SlashHeaderMapper(maingen string) codejen.FileMapper {
46 | return func(f codejen.File) (codejen.File, error) {
47 | // Never inject on certain filetypes, it's never valid
48 | switch filepath.Ext(f.RelativePath) {
49 | case ".json", ".yml", ".yaml", ".md":
50 | return f, nil
51 | default:
52 | buf := new(bytes.Buffer)
53 | if err := tmpls.Lookup("gen_header.tmpl").Execute(buf, tvars_gen_header{
54 | MainGenerator: maingen,
55 | Using: f.From,
56 | }); err != nil {
57 | return codejen.File{}, fmt.Errorf("failed executing gen header template: %w", err)
58 | }
59 | fmt.Fprint(buf, string(f.Data))
60 | f.Data = buf.Bytes()
61 | }
62 | return f, nil
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/internal/provider/provider.go:
--------------------------------------------------------------------------------
1 | package provider
2 |
3 | import (
4 | "context"
5 | "net/http"
6 |
7 | "github.com/hashicorp/terraform-plugin-framework/datasource"
8 | "github.com/hashicorp/terraform-plugin-framework/provider"
9 | "github.com/hashicorp/terraform-plugin-framework/provider/schema"
10 | "github.com/hashicorp/terraform-plugin-framework/resource"
11 | )
12 |
13 | // Ensure schemasProvider satisfies various provider interfaces.
14 | var _ provider.Provider = &schemasProvider{}
15 |
16 | // schemasProvider defines the provider implementation.
17 | type schemasProvider struct {
18 | // version is set to the provider version on release, "dev" when the
19 | // provider is built and ran locally, and "test" when running acceptance
20 | // testing.
21 | version string
22 | }
23 |
24 | // schemasProviderModel describes the provider data model.
25 | type schemasProviderModel struct {
26 | }
27 |
28 | func (p *schemasProvider) Metadata(ctx context.Context, req provider.MetadataRequest, resp *provider.MetadataResponse) {
29 | resp.TypeName = "schemas"
30 | resp.Version = p.version
31 | }
32 |
33 | func (p *schemasProvider) Schema(ctx context.Context, req provider.SchemaRequest, resp *provider.SchemaResponse) {
34 | resp.Schema = schema.Schema{
35 | Attributes: map[string]schema.Attribute{},
36 | }
37 | }
38 |
39 | func (p *schemasProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {
40 | var data schemasProviderModel
41 |
42 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
43 |
44 | if resp.Diagnostics.HasError() {
45 | return
46 | }
47 |
48 | // Configuration values are now available.
49 | // if data.Endpoint.IsNull() { /* ... */ }
50 |
51 | // Example client configuration for data sources and resources
52 | client := http.DefaultClient
53 | resp.DataSourceData = client
54 | resp.ResourceData = client
55 | }
56 |
57 | func (p *schemasProvider) Resources(ctx context.Context) []func() resource.Resource {
58 | return []func() resource.Resource{}
59 | }
60 |
61 | func (p *schemasProvider) DataSources(ctx context.Context) []func() datasource.DataSource {
62 | return datasources
63 | }
64 |
65 | func New(version string) func() provider.Provider {
66 | return func() provider.Provider {
67 | return &schemasProvider{
68 | version: version,
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/gen/internal/jenny_eachmajorcomposable.go:
--------------------------------------------------------------------------------
1 | package jen
2 |
3 | import (
4 | "fmt"
5 | "path/filepath"
6 | "strings"
7 |
8 | "github.com/grafana/codejen"
9 | "github.com/grafana/grafana/pkg/codegen"
10 | "github.com/grafana/kindsys"
11 | )
12 |
13 | // TODO remove this once there's a standard jenny for this...somewhere in core.
14 | func ComposableLatestMajorsOrXJenny(parentdir string, useParentDirOnly bool, inner codejen.OneToOne[codegen.SchemaForGen]) codejen.OneToMany[kindsys.Composable] {
15 | if inner == nil {
16 | panic("inner jenny must not be nil")
17 | }
18 |
19 | return &clmox{
20 | parentdir: parentdir,
21 | useParentDirOnly: useParentDirOnly,
22 | inner: inner,
23 | }
24 | }
25 |
26 | type clmox struct {
27 | parentdir string
28 | useParentDirOnly bool // Do not create sub folders in parentdir.
29 | inner codejen.OneToOne[codegen.SchemaForGen]
30 | }
31 |
32 | func (j *clmox) JennyName() string {
33 | return "ComposableLatestMajorsOrXJenny"
34 | }
35 |
36 | func (j *clmox) Generate(k kindsys.Composable) (codejen.Files, error) {
37 | si, err := kindsys.FindSchemaInterface(k.Def().Properties.SchemaInterface)
38 | if err != nil {
39 | panic(err)
40 | }
41 | sfg := codegen.SchemaForGen{
42 | Name: k.Lineage().Name(),
43 | IsGroup: si.IsGroup(),
44 | }
45 |
46 | // TODO adapt this once we figure out consistent naming
47 | // nam := fmt.Sprintf("%s-%s", strings.ToLower(decl.Info.Meta().Id), strings.ToLower(sfg.Name))
48 | nam := strings.ToLower(sfg.Name)
49 |
50 | do := func(sfg codegen.SchemaForGen, infix string) (codejen.Files, error) {
51 | f, err := j.inner.Generate(sfg)
52 | if err != nil {
53 | return nil, fmt.Errorf("%s jenny failed on %s schema for %s: %w", j.inner.JennyName(), sfg.Schema.Version(), nam, err)
54 | }
55 | if f == nil || !f.Exists() {
56 | return nil, nil
57 | }
58 |
59 | if j.useParentDirOnly {
60 | f.RelativePath = filepath.Join(j.parentdir, strings.ToLower(f.RelativePath))
61 | } else {
62 | f.RelativePath = filepath.Join(j.parentdir, strings.ToLower(strings.TrimSuffix(sfg.Name, si.Name())), strings.ToLower(si.Name()), infix, strings.ToLower(f.RelativePath))
63 | }
64 | f.From = append(f.From, j)
65 | return codejen.Files{*f}, nil
66 | }
67 |
68 | // TODO uncomment this latter half once plugins are fully converted to new system
69 | // if comm.Maturity.Less(kindsys.MaturityStable) {
70 | sfg.Schema = k.Lineage().Latest()
71 | return do(sfg, "x")
72 | // }
73 |
74 | // var fl codejen.Files
75 | // for sch := decl.Lineage.First(); sch != nil; sch = sch.Successor() {
76 | // sfg.Schema = sch.LatestInMajor()
77 | // files, err := do(sfg, fmt.Sprintf("v%v", sch.Version()[0]))
78 | // if err != nil {
79 | // return nil, err
80 | // }
81 | // fl = append(fl, files...)
82 | // }
83 | // if fl.Validate() != nil {
84 | // return nil, fl.Validate()
85 | // }
86 | // return fl, nil
87 | }
88 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | # Terraform Provider testing workflow.
2 | name: Tests
3 |
4 | # This GitHub action runs your tests for each pull request and push.
5 | # Optionally, you can turn it on using a schedule for regular testing.
6 | on:
7 | pull_request:
8 | paths-ignore:
9 | - 'README.md'
10 | push:
11 | paths-ignore:
12 | - 'README.md'
13 |
14 | # Testing only needs permissions to read the repository contents.
15 | permissions:
16 | contents: read
17 |
18 | jobs:
19 | # Ensure project builds before running testing matrix
20 | build:
21 | name: Build
22 | runs-on: ubuntu-latest
23 | timeout-minutes: 5
24 | steps:
25 | - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
26 | with:
27 | persist-credentials: false
28 | - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
29 | with:
30 | go-version-file: 'go.mod'
31 | cache: true
32 | - run: go mod download
33 | - run: go build -v .
34 | - name: Run linters
35 | uses: golangci/golangci-lint-action@3a919529898de77ec3da873e3063ca4b10e7f5cc # v3.7.0
36 | with:
37 | version: v1.52.2
38 |
39 | generate:
40 | runs-on: ubuntu-latest
41 | steps:
42 | - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
43 | with:
44 | persist-credentials: false
45 | - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
46 | with:
47 | go-version-file: 'go.mod'
48 | cache: true
49 | - run: rm -rf ./internal/provider/*_gen.go
50 | - run: cd ./gen && MIN_MATURITY=merged go generate ./
51 | - run: go generate ./
52 | - name: git diff
53 | run: |
54 | git diff --compact-summary --exit-code || \
55 | (echo; echo "Unexpected difference in directories after code generation. Run 'go generate ./...' command and commit."; exit 1)
56 |
57 | # Run acceptance tests in a matrix with Terraform CLI versions
58 | test:
59 | name: Terraform Provider Acceptance Tests
60 | needs: build
61 | runs-on: ubuntu-latest
62 | timeout-minutes: 15
63 | strategy:
64 | fail-fast: false
65 | matrix:
66 | # list whatever Terraform versions here you would like to support
67 | terraform:
68 | - '1.0.*'
69 | - '1.1.*'
70 | - '1.2.*'
71 | steps:
72 | - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
73 | with:
74 | persist-credentials: false
75 | - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
76 | with:
77 | go-version-file: 'go.mod'
78 | cache: true
79 | - uses: hashicorp/setup-terraform@633666f66e0061ca3b725c73b2ec20cd13a8fdd1 # v2.0.3
80 | with:
81 | terraform_version: ${{ matrix.terraform }}
82 | terraform_wrapper: false
83 | - run: go mod download
84 | - env:
85 | TF_ACC: "1"
86 | run: go test -v -cover ./internal/provider/
87 | timeout-minutes: 10
88 |
--------------------------------------------------------------------------------
/gen/gen.go:
--------------------------------------------------------------------------------
1 | //go:generate go run gen.go
2 |
3 | package main
4 |
5 | import (
6 | "context"
7 | "fmt"
8 | "os"
9 |
10 | "github.com/grafana/codejen"
11 | "github.com/grafana/grafana/pkg/plugins/pfs/corelist"
12 | "github.com/grafana/grafana/pkg/registry/corekind"
13 | "github.com/grafana/kindsys"
14 | jen "github.com/grafana/terraform-provider-schemas/gen/internal"
15 | "github.com/grafana/terraform-provider-schemas/gen/terraform"
16 | )
17 |
18 | func main() {
19 | // Load all core and composable kinds.
20 | var corek []kindsys.Kind
21 | var compok []kindsys.Composable
22 |
23 | minMaturity :=
24 | func() kindsys.Maturity {
25 | switch os.Getenv("MIN_MATURITY") {
26 | case "merged":
27 | return kindsys.MaturityMerged
28 | case "experimental":
29 | return kindsys.MaturityExperimental
30 | case "stable":
31 | return kindsys.MaturityStable
32 | case "mature":
33 | return kindsys.MaturityMature
34 | default:
35 | return kindsys.MaturityExperimental
36 | }
37 | }()
38 |
39 | for _, kind := range corekind.NewBase(nil).All() {
40 | // This provider should only generate dashboard-related datasources for now
41 | if kind.Name() != "Dashboard" {
42 | continue
43 | }
44 | if kind.Maturity().Less(minMaturity) {
45 | continue
46 | }
47 | corek = append(corek, kind)
48 | }
49 |
50 | // Skip data sources that only have definitions
51 | skippedPlugins := map[string]bool{
52 | "AzureMonitorDataQuery": true,
53 | "CloudWatchDataQuery": true,
54 | "GoogleCloudMonitoringDataQuery": true,
55 | "TempoDataQuery": true,
56 | }
57 | for _, pp := range corelist.New(nil) {
58 | for _, kind := range pp.ComposableKinds {
59 | _, skipped := skippedPlugins[kind.Lineage().Name()]
60 | if kind.Maturity().Less(minMaturity) || skipped {
61 | continue
62 | }
63 | compok = append(compok, kind)
64 | }
65 | }
66 |
67 | // Add all jennies.
68 | jfs := codejen.NewFS()
69 | tj := getJennies()
70 |
71 | ckfs, err := tj.Core.GenerateFS(corek...)
72 | die(err)
73 | die(jfs.Merge(ckfs))
74 | ckfs, err = tj.Composable.GenerateFS(compok...)
75 | die(err)
76 | die(jfs.Merge(ckfs))
77 |
78 | if _, set := os.LookupEnv("CODEGEN_VERIFY"); set {
79 | if err = jfs.Verify(context.Background(), ""); err != nil {
80 | die(fmt.Errorf("generated code is out of sync with inputs:\n%s\nrun `make gen-cue` to regenerate", err))
81 | }
82 | } else if err = jfs.Write(context.Background(), ""); err != nil {
83 | die(fmt.Errorf("error while writing generated code to disk:\n%s", err))
84 | }
85 | }
86 |
87 | // Get all jennies for Terraform.
88 | func getJennies() jen.TargetJennies {
89 | header := "terraform"
90 | path := "../internal/provider"
91 | tj := terraform.JenniesForTerraform()
92 |
93 | tj.Core.AddPostprocessors(jen.Prefixer(path), jen.SlashHeaderMapper(header))
94 | tj.Composable.AddPostprocessors(jen.Prefixer(path), jen.SlashHeaderMapper(header))
95 |
96 | return tj
97 | }
98 |
99 | func die(err error) {
100 | if err != nil {
101 | fmt.Fprint(os.Stderr, err, "\n")
102 | os.Exit(1)
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | page_title: "Schemas Provider"
3 | description: |-
4 | Generated provider to manage Grafana dashboards.
5 | ---
6 |
7 | # Schemas Provider
8 |
9 | This provider provides data sources to manage Grafana [dashboards](https://grafana.com/docs/grafana/latest/dashboards/). You should use it with the [Grafana Terraform Provider](https://registry.terraform.io/providers/grafana/grafana/latest). It is generated from the [CUE schemas](https://github.com/grafana/grafana/blob/main/kinds/dashboard/dashboard_kind.cue) defined in the Grafana repository to ensure it stays up-to-date.
10 |
11 | The code in this repository should be considered experimental. It comes with no support, but we are keen to receive feedback on the product and suggestions on how to improve it, though we cannot commit to resolution of any particular issue. No SLAs are available. It is not meant to be used in production environments, and the risks are unknown/high.
12 |
13 | Our goal is for these generated data sources to become a part of our official Grafana provider once this project becomes more mature. At this time, we are not planning to create a migration path for data sources created with the `schemas` provider when they are merged into the `grafana` provider. Also, this work is subject to signficant changes as we iterate towards that level of quality.
14 |
15 | ## Maturity
16 |
17 | Grafana Labs defines experimental features as follows:
18 |
19 | > Projects and features in the Experimental stage are supported only by the Engineering
20 | teams; on-call support is not available. Documentation is either limited or not provided
21 | outside of code comments. No SLA is provided.
22 | >
23 | > Experimental projects or features are primarily intended for open source engineers who
24 | want to participate in ensuring systems stability, and to gain consensus and approval
25 | for open source governance projects.
26 | >
27 | > Projects and features in the Experimental phase are not meant to be used in production
28 | environments, and the risks are unknown/high.
29 |
30 | ## Example usage
31 |
32 | Configure the [Grafana Terraform Provider](https://registry.terraform.io/providers/grafana/grafana/latest) to access your Grafana instance (see [documentation](https://grafana.com/docs/grafana-cloud/infrastructure-as-code/terraform/)). Then use this Grafana Schemas Terraform provider to create your dashboards.
33 |
34 | ```
35 | terraform {
36 | required_providers {
37 | schemas = {
38 | source = "grafana/schemas"
39 | version = "0.1.0"
40 | }
41 | grafana = {
42 | source = "grafana/grafana"
43 | version = "1.36.1"
44 | }
45 | }
46 | }
47 | provider "grafana" {
48 | url = "http://localhost:3000"
49 | auth = "admin:admin"
50 | }
51 | resource "grafana_dashboard" "example" {
52 | config_json = data.schemas_core_dashboard.my_dashboard.rendered_json
53 | }
54 | data "schemas_core_dashboard" "my_dashboard" {
55 | title = "My Dashboard"
56 | time = {
57 | from = "now-1h"
58 | }
59 | panels = [
60 | data.schemas_panel_stat.my_panel.rendered_json,
61 | ]
62 | }
63 | data "schemas_panel_stat" "my_panel" {
64 | title = "My Panel"
65 | grid_pos = {
66 | h = 4
67 | w = 6
68 | x = 0
69 | y = 0
70 | }
71 | }
72 | ```
--------------------------------------------------------------------------------
/templates/index.md.tmpl:
--------------------------------------------------------------------------------
1 | ---
2 | page_title: "Schemas Provider"
3 | description: |-
4 | Generated provider to manage Grafana dashboards.
5 | ---
6 |
7 | # Schemas Provider
8 |
9 | This provider provides data sources to manage Grafana [dashboards](https://grafana.com/docs/grafana/latest/dashboards/). You should use it with the [Grafana Terraform Provider](https://registry.terraform.io/providers/grafana/grafana/latest). It is generated from the [CUE schemas](https://github.com/grafana/grafana/blob/main/kinds/dashboard/dashboard_kind.cue) defined in the Grafana repository to ensure it stays up-to-date.
10 |
11 | The code in this repository should be considered experimental. It comes with no support, but we are keen to receive feedback on the product and suggestions on how to improve it, though we cannot commit to resolution of any particular issue. No SLAs are available. It is not meant to be used in production environments, and the risks are unknown/high.
12 |
13 | Our goal is for these generated data sources to become a part of our official Grafana provider once this project becomes more mature. At this time, we are not planning to create a migration path for data sources created with the `schemas` provider when they are merged into the `grafana` provider. Also, this work is subject to signficant changes as we iterate towards that level of quality.
14 |
15 | ## Maturity
16 |
17 | Grafana Labs defines experimental features as follows:
18 |
19 | > Projects and features in the Experimental stage are supported only by the Engineering
20 | teams; on-call support is not available. Documentation is either limited or not provided
21 | outside of code comments. No SLA is provided.
22 | >
23 | > Experimental projects or features are primarily intended for open source engineers who
24 | want to participate in ensuring systems stability, and to gain consensus and approval
25 | for open source governance projects.
26 | >
27 | > Projects and features in the Experimental phase are not meant to be used in production
28 | environments, and the risks are unknown/high.
29 |
30 | ## Example usage
31 |
32 | Configure the [Grafana Terraform Provider](https://registry.terraform.io/providers/grafana/grafana/latest) to access your Grafana instance (see [documentation](https://grafana.com/docs/grafana-cloud/infrastructure-as-code/terraform/)). Then use this Grafana Schemas Terraform provider to create your dashboards.
33 |
34 | ```
35 | terraform {
36 | required_providers {
37 | schemas = {
38 | source = "grafana/schemas"
39 | version = "0.1.0"
40 | }
41 | grafana = {
42 | source = "grafana/grafana"
43 | version = "1.36.1"
44 | }
45 | }
46 | }
47 | provider "grafana" {
48 | url = "http://localhost:3000"
49 | auth = "admin:admin"
50 | }
51 | resource "grafana_dashboard" "example" {
52 | config_json = data.schemas_core_dashboard.my_dashboard.rendered_json
53 | }
54 | data "schemas_core_dashboard" "my_dashboard" {
55 | title = "My Dashboard"
56 | time = {
57 | from = "now-1h"
58 | }
59 | panels = [
60 | data.schemas_panel_stat.my_panel.rendered_json,
61 | ]
62 | }
63 | data "schemas_panel_stat" "my_panel" {
64 | title = "My Panel"
65 | grid_pos = {
66 | h = 4
67 | w = 6
68 | x = 0
69 | y = 0
70 | }
71 | }
72 | ```
--------------------------------------------------------------------------------
/.github/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6 |
7 | ## Our Standards
8 |
9 | Examples of behavior that contributes to creating a positive environment include:
10 |
11 | - Using welcoming and inclusive language
12 | - Being respectful of differing viewpoints and experiences
13 | - Gracefully accepting constructive criticism
14 | - Focusing on what is best for the community
15 | - Showing empathy towards other community members
16 |
17 | Examples of unacceptable behavior by participants include:
18 |
19 | - The use of sexualized language or imagery and unwelcome sexual attention or advances
20 | - Trolling, insulting/derogatory comments, and personal or political attacks
21 | - Public or private harassment
22 | - Publishing others' private information, such as a physical or electronic address, without explicit permission
23 | - Other conduct which could reasonably be considered inappropriate in a professional setting
24 |
25 | ## Our Responsibilities
26 |
27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28 |
29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30 |
31 | ## Scope
32 |
33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34 |
35 | ## Enforcement
36 |
37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at conduct@grafana.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38 |
39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40 |
41 | ## Attribution
42 |
43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44 |
45 | [homepage]: http://contributor-covenant.org
46 | [version]: http://contributor-covenant.org/version/1/4/
47 |
--------------------------------------------------------------------------------
/gen/terraform/cuetf/types/node.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "fmt"
5 | "strings"
6 |
7 | "cuelang.org/go/cue"
8 | "github.com/grafana/terraform-provider-schemas/gen/terraform/cuetf/internal/utils"
9 | )
10 |
11 | type Node struct {
12 | Name string
13 | Kind cue.Kind
14 | SubKind cue.Kind // For list only, kind of its elements
15 | IsMap bool
16 | IsDisjunction bool
17 | Optional bool
18 | Default string
19 | Doc string
20 | Children []Node
21 | Parent *Node
22 | DisjunctionKinds []cue.Kind
23 | }
24 |
25 | func (n *Node) TerraformModelField(structName string) string {
26 | kind := kindMappings[n.Kind]
27 | subKind := kindMappings[n.SubKind]
28 | typeStr := ""
29 | switch true {
30 | case n.Kind == cue.ListKind && n.SubKind == cue.StructKind:
31 | typeStr = "[]" + structName + "_" + utils.Title(n.Name)
32 | case n.Kind == cue.ListKind && subKind != nil:
33 | typeStr = "types.List"
34 | case n.Kind == cue.StructKind:
35 | if n.IsMap {
36 | typeStr = "map[string]"
37 | }
38 | typeStr += structName + "_" + utils.Title(n.Name)
39 | if n.Optional {
40 | typeStr = "*" + typeStr
41 | }
42 | default:
43 | typeStr = "types." + kind.terraformType
44 | }
45 |
46 | return fmt.Sprintf("%s %s `tfsdk:\"%s\"`", utils.ToCamelCase(n.Name), typeStr, utils.ToSnakeCase(n.Name))
47 | }
48 |
49 | func (n *Node) JSONModelField() string {
50 | kind := kindMappings[n.Kind]
51 | subKind := kindMappings[n.SubKind]
52 | golangType := ""
53 | switch true {
54 | case n.Kind == cue.ListKind && n.SubKind == cue.StructKind:
55 | golangType = "[]interface{}"
56 | case n.Kind == cue.ListKind && subKind != nil:
57 | golangType = "[]" + subKind.golangType
58 | case n.Kind == cue.StructKind || len(n.DisjunctionKinds) > 0:
59 | golangType = "interface{}"
60 | default:
61 | golangType = kind.golangType
62 | }
63 |
64 | omitStr := ""
65 | if n.Optional {
66 | if !strings.HasPrefix(golangType, "[]") && golangType != "interface{}" {
67 | golangType = "*" + golangType
68 | }
69 | omitStr = ",omitempty"
70 | }
71 |
72 | return fmt.Sprintf("%s %s `json:\"%s%s\"`", utils.ToCamelCase(n.Name), golangType, n.Name, omitStr)
73 | }
74 |
75 | func (n *Node) TerraformType() string {
76 | if kindMappings[n.Kind] == nil {
77 | return ""
78 | }
79 |
80 | return kindMappings[n.Kind].terraformType
81 | }
82 |
83 | func (n *Node) SubTerraformType() string {
84 | if kindMappings[n.SubKind] == nil {
85 | return ""
86 | }
87 |
88 | return kindMappings[n.SubKind].terraformType
89 | }
90 |
91 | func (n *Node) subGolangType() string {
92 | if kindMappings[n.SubKind] == nil {
93 | return ""
94 | }
95 |
96 | return kindMappings[n.SubKind].golangType
97 | }
98 |
99 | func (n *Node) terraformFunc() string {
100 | if kindMappings[n.Kind] == nil {
101 | return ""
102 | }
103 |
104 | terraformFunc := kindMappings[n.Kind].terraformFunc
105 | if n.Optional {
106 | return terraformFunc + "Pointer()"
107 | }
108 |
109 | return terraformFunc + "()"
110 | }
111 |
112 | func (n *Node) subTerraformFunc() string {
113 | if kindMappings[n.SubKind] == nil {
114 | return ""
115 | }
116 |
117 | return kindMappings[n.SubKind].terraformFunc + "()"
118 | }
119 |
120 | func (n *Node) IsGenerated() bool {
121 | return kindMappings[n.Kind] != nil ||
122 | (n.Kind == cue.ListKind && kindMappings[n.SubKind] != nil) ||
123 | (n.Kind == cue.ListKind && n.SubKind == cue.StructKind) ||
124 | (n.Kind == cue.StructKind)
125 | }
126 |
--------------------------------------------------------------------------------
/examples/schemas_core_dashboard/prometheus/dashboard.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_providers {
3 | schemas = {
4 | source = "grafana/schemas"
5 | version = "0.1.0"
6 | }
7 | grafana = {
8 | source = "grafana/grafana"
9 | version = "1.36.1"
10 | }
11 | }
12 | }
13 |
14 | provider "grafana" {
15 | url = "http://localhost:3000"
16 | auth = "admin:admin"
17 | }
18 |
19 | resource "grafana_dashboard" "example" {
20 | config_json = data.schemas_core_dashboard.prometheus_dashboard.rendered_json
21 | }
22 |
23 | resource "grafana_data_source" "prometheus" {
24 | type = "prometheus"
25 | name = "Prometheus"
26 | url = "http://localhost:9090"
27 | basic_auth_enabled = false
28 | }
29 |
30 | data "schemas_core_dashboard" "prometheus_dashboard" {
31 | title = "Prometheus Dashboard"
32 |
33 | time = {
34 | from = "now-1h"
35 | }
36 |
37 | panels = [
38 | data.schemas_panel_stat.disk.rendered_json,
39 | data.schemas_panel_time_series.cpu_usage.rendered_json,
40 | data.schemas_panel_time_series.disk_usage.rendered_json,
41 | ]
42 | }
43 |
44 | data "schemas_panel_stat" "disk" {
45 | title = "Disk"
46 |
47 | datasource = {
48 | uid = resource.grafana_data_source.prometheus.uid
49 | type = resource.grafana_data_source.prometheus.type
50 | }
51 |
52 | grid_pos = {
53 | h = 4
54 | w = 6
55 | x = 8
56 | y = 0
57 | }
58 |
59 | field_config = {
60 | defaults = {
61 | unit = "percentunit"
62 | }
63 | }
64 |
65 | targets = [
66 | data.schemas_query_prometheus.disk_target.rendered_json
67 | ]
68 | }
69 |
70 | data "schemas_query_prometheus" "cores_target" {
71 | expr = "count(count by(cpu)(node_cpu_seconds_total))"
72 | format = "time_series"
73 | ref_id = "A"
74 | }
75 |
76 | data "schemas_panel_time_series" "cpu_usage" {
77 | title = "CPU usage"
78 |
79 | datasource = {
80 | uid = resource.grafana_data_source.prometheus.uid
81 | type = resource.grafana_data_source.prometheus.type
82 | }
83 |
84 | grid_pos = {
85 | h = 8
86 | w = 12
87 | x = 0
88 | y = 4
89 | }
90 |
91 | options = {
92 | legend = {
93 | calcs = [
94 | "mean",
95 | "lastNotNull",
96 | "max",
97 | "min"
98 | ]
99 | display_mode = "table"
100 | placement = "bottom"
101 | show_legend = true
102 | }
103 | }
104 |
105 | targets = [
106 | data.schemas_query_prometheus.cpu_target.rendered_json
107 | ]
108 | }
109 |
110 | data "schemas_query_prometheus" "cpu_target" {
111 | expr = "sum by(mode) (irate(node_cpu_seconds_total{mode!=\"idle\"}[5m]))"
112 | format = "time_series"
113 | ref_id = "A"
114 | }
115 |
116 | data "schemas_panel_time_series" "disk_usage" {
117 | title = "Disk I/O utilization"
118 |
119 | datasource = {
120 | uid = resource.grafana_data_source.prometheus.uid
121 | type = resource.grafana_data_source.prometheus.type
122 | }
123 |
124 | grid_pos = {
125 | h = 8
126 | w = 12
127 | x = 12
128 | y = 4
129 | }
130 |
131 | options = {
132 | legend = {
133 | calcs = [
134 | "mean",
135 | "lastNotNull",
136 | "max",
137 | "min"
138 | ]
139 | display_mode = "table"
140 | placement = "bottom"
141 | show_legend = true
142 | }
143 | }
144 |
145 | field_config = {
146 | defaults = {
147 | unit = "percentunit"
148 | min = 0
149 | max = 1
150 | }
151 | }
152 |
153 | targets = [
154 | data.schemas_query_prometheus.disk_target.rendered_json
155 | ]
156 | }
157 |
158 | data "schemas_query_prometheus" "disk_target" {
159 | expr = "sum(irate(node_disk_io_time_seconds_total[5m]))"
160 | format = "time_series"
161 | ref_id = "A"
162 | }
163 |
--------------------------------------------------------------------------------
/docs/data-sources/query_test_data.md:
--------------------------------------------------------------------------------
1 | ---
2 | # generated by https://github.com/hashicorp/terraform-plugin-docs
3 | page_title: "schemas_query_test_data Data Source - terraform-provider-schemas"
4 | subcategory: ""
5 | description: |-
6 |
7 | ---
8 |
9 | # schemas_query_test_data (Data Source)
10 |
11 |
12 |
13 |
14 |
15 |
16 | ## Schema
17 |
18 | ### Required
19 |
20 | - `ref_id` (String) A unique identifier for the query within the list of targets.
21 | In server side expressions, the refId is used as a variable name to identify results.
22 | By default, the UI will assign A->Z; however setting meaningful names may be useful.
23 |
24 | ### Optional
25 |
26 | - `alias` (String)
27 | - `channel` (String)
28 | - `csv_content` (String)
29 | - `csv_file_name` (String)
30 | - `csv_wave` (Attributes List) (see [below for nested schema](#nestedatt--csv_wave))
31 | - `drop_percent` (Number) Drop percentage (the chance we will lose a point 0-100)
32 | - `error_type` (String)
33 | - `hide` (Boolean) true if query is disabled (ie should not be returned to the dashboard)
34 | Note this does not always imply that the query should not be executed since
35 | the results from a hidden query may be used as the input to other queries (SSE etc)
36 | - `labels` (String)
37 | - `level_column` (Boolean)
38 | - `lines` (Number)
39 | - `nodes` (Attributes) (see [below for nested schema](#nestedatt--nodes))
40 | - `pulse_wave` (Attributes) (see [below for nested schema](#nestedatt--pulse_wave))
41 | - `query_type` (String) Specify the query flavor
42 | TODO make this required and give it a default
43 | - `raw_frame_content` (String)
44 | - `scenario_id` (String) Defaults to "random_walk".
45 | - `series_count` (Number)
46 | - `sim` (Attributes) (see [below for nested schema](#nestedatt--sim))
47 | - `span_count` (Number)
48 | - `stream` (Attributes) (see [below for nested schema](#nestedatt--stream))
49 | - `string_input` (String)
50 | - `usa` (Attributes) (see [below for nested schema](#nestedatt--usa))
51 |
52 | ### Read-Only
53 |
54 | - `rendered_json` (String) This datasource rendered as JSON
55 |
56 |
57 | ### Nested Schema for `csv_wave`
58 |
59 | Optional:
60 |
61 | - `labels` (String)
62 | - `name` (String)
63 | - `time_step` (Number)
64 | - `values_csv` (String)
65 |
66 |
67 |
68 | ### Nested Schema for `nodes`
69 |
70 | Optional:
71 |
72 | - `count` (Number)
73 | - `type` (String)
74 |
75 |
76 |
77 | ### Nested Schema for `pulse_wave`
78 |
79 | Optional:
80 |
81 | - `off_count` (Number)
82 | - `off_value` (Number)
83 | - `on_count` (Number)
84 | - `on_value` (Number)
85 | - `time_step` (Number)
86 |
87 |
88 |
89 | ### Nested Schema for `sim`
90 |
91 | Optional:
92 |
93 | - `config` (Attributes) (see [below for nested schema](#nestedatt--sim--config))
94 | - `key` (Attributes) (see [below for nested schema](#nestedatt--sim--key))
95 | - `last` (Boolean)
96 | - `stream` (Boolean)
97 |
98 |
99 | ### Nested Schema for `sim.config`
100 |
101 |
102 |
103 | ### Nested Schema for `sim.key`
104 |
105 | Required:
106 |
107 | - `tick` (Number)
108 | - `type` (String)
109 |
110 | Optional:
111 |
112 | - `uid` (String)
113 |
114 |
115 |
116 |
117 | ### Nested Schema for `stream`
118 |
119 | Required:
120 |
121 | - `noise` (Number)
122 | - `speed` (Number)
123 | - `spread` (Number)
124 | - `type` (String)
125 |
126 | Optional:
127 |
128 | - `bands` (Number)
129 | - `url` (String)
130 |
131 |
132 |
133 | ### Nested Schema for `usa`
134 |
135 | Optional:
136 |
137 | - `fields` (List of String)
138 | - `mode` (String)
139 | - `period` (String)
140 | - `states` (List of String)
141 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Grafana Schemas Terraform Provider (experimental)
2 |
3 | This is a generated provider to manage Grafana dashboards.
4 |
5 | The code in this repository should be considered experimental. It comes with no support, but we are keen to receive feedback on the product and suggestions on how to improve it, though we cannot commit to resolution of any particular issue. No SLAs are available. It is not meant to be used in production environments, and the risks are unknown/high.
6 |
7 | Our goal is for these generated data sources to become a part of our official Grafana provider once this project becomes more mature. At this time, we are not planning to create a migration path for data sources created with the `schemas` provider when they are merged into the `grafana` provider. Also, this work is subject to signficant changes as we iterate towards that level of quality.
8 |
9 | ## Requirements
10 |
11 | - [Terraform](https://www.terraform.io/downloads.html) >= 1.0
12 |
13 | ## Maturity
14 |
15 | Grafana Labs defines experimental features as follows:
16 |
17 | > Projects and features in the Experimental stage are supported only by the Engineering
18 | teams; on-call support is not available. Documentation is either limited or not provided
19 | outside of code comments. No SLA is provided.
20 | >
21 | > Experimental projects or features are primarily intended for open source engineers who
22 | want to participate in ensuring systems stability, and to gain consensus and approval
23 | for open source governance projects.
24 | >
25 | > Projects and features in the Experimental phase are not meant to be used in production
26 | environments, and the risks are unknown/high.
27 |
28 | ## Usage
29 |
30 | This provider should be used with the [Grafana Terraform Provider](https://registry.terraform.io/providers/grafana/grafana/latest). It is generated from the [CUE schemas](https://github.com/grafana/grafana/blob/main/kinds/dashboard/dashboard_kind.cue) defined in the Grafana repository to ensure it stays up-to-date.
31 |
32 | Configure the [Grafana Terraform Provider](https://registry.terraform.io/providers/grafana/grafana/latest) to access your Grafana instance (see [documentation](https://grafana.com/docs/grafana-cloud/infrastructure-as-code/terraform/)). Then use this Grafana Schemas Terraform provider to create your dashboards.
33 |
34 | ```
35 | terraform {
36 | required_providers {
37 | schemas = {
38 | source = "grafana/schemas"
39 | version = "0.1.0"
40 | }
41 | grafana = {
42 | source = "grafana/grafana"
43 | version = "1.36.1"
44 | }
45 | }
46 | }
47 |
48 | provider "grafana" {
49 | url = "http://localhost:3000"
50 | auth = "admin:admin"
51 | }
52 |
53 | data "schemas_core_dashboard" "my_dashboard" {
54 | title = "My Dashboard"
55 |
56 | time = {
57 | from = "now-1h"
58 | }
59 |
60 | panels = [
61 | data.schemas_panel_stat.my_panel.rendered_json,
62 | ]
63 | }
64 |
65 | data "schemas_panel_stat" "my_panel" {
66 | title = "My Panel"
67 |
68 | grid_pos = {
69 | h = 4
70 | w = 6
71 | x = 0
72 | y = 0
73 | }
74 | }
75 |
76 | resource "grafana_dashboard" "example" {
77 | config_json = data.schemas_core_dashboard.my_dashboard.rendered_json
78 | }
79 | ```
80 |
81 | More examples are available in the ["examples"](https://github.com/grafana/terraform-provider-schemas/tree/main/examples/data-sources/schemas_core_dashboard) folder.
82 |
83 | ## Development
84 |
85 | ### Requirements
86 |
87 | - [Terraform](https://www.terraform.io/downloads.html) >= 1.0
88 | - [Go](https://golang.org/doc/install) >= 1.19
89 |
90 | ### Building The Provider
91 |
92 | 1. Clone the repository
93 | 1. Enter the repository directory
94 | 1. Build the provider using the Go `install` command:
95 |
96 | ```shell
97 | go install
98 | ```
99 |
100 | If you want to re-generate the provider, use the `make generate` command.
101 |
102 | ### Adding Dependencies
103 |
104 | This provider uses [Go modules](https://github.com/golang/go/wiki/Modules).
105 | Please see the Go documentation for the most up to date information about using Go modules.
106 |
107 | To add a new dependency `github.com/author/dependency` to your Terraform provider:
108 |
109 | ```shell
110 | go get github.com/author/dependency
111 | go mod tidy
112 | ```
113 |
114 | Then commit the changes to `go.mod` and `go.sum`.
115 |
116 | ### Developing the Provider
117 |
118 | If you wish to work on the provider, you'll first need [Go](http://www.golang.org) installed on your machine (see [Requirements](#requirements) above).
119 |
120 | To compile the provider, run `go install`. This will build the provider and put the provider binary in the `$GOPATH/bin` directory.
121 |
122 | To generate or update documentation, run `go generate`.
123 |
124 | In order to run the full suite of Acceptance tests, run `make testacc`.
125 |
126 | *Note:* Acceptance tests create real resources, and often cost money to run.
127 |
128 | ```shell
129 | make testacc
130 | ```
131 |
--------------------------------------------------------------------------------
/gen/terraform/cuetf/templates/datasource.tmpl:
--------------------------------------------------------------------------------
1 | package provider
2 |
3 | import (
4 | "context"
5 | "encoding/json"
6 |
7 | "github.com/hashicorp/terraform-plugin-framework/attr"
8 | "github.com/hashicorp/terraform-plugin-framework/datasource"
9 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema"
10 | "github.com/hashicorp/terraform-plugin-framework/diag"
11 | "github.com/hashicorp/terraform-plugin-framework/types"
12 | "github.com/hashicorp/terraform-plugin-log/tflog"
13 | )
14 |
15 | // Ensure that the imports are used to avoid compiler errors.
16 | var _ attr.Value
17 | var _ diag.Diagnostic
18 |
19 | // Ensure provider defined types fully satisfy framework interfaces.
20 | var (
21 | _ datasource.DataSource = &{{.StructName}}{}
22 | _ datasource.DataSourceWithConfigure = &{{.StructName}}{}
23 | )
24 |
25 | func New{{.StructName}}() datasource.DataSource {
26 | return &{{.StructName}}{}
27 | }
28 |
29 | // {{.StructName}} defines the data source implementation.
30 | type {{.StructName}} struct {}
31 |
32 | {{ .Models }}
33 |
34 | func (d *{{.StructName}}) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
35 | resp.TypeName = req.ProviderTypeName + "_{{.Name}}"
36 | }
37 |
38 | func (d *{{.StructName}}) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
39 | resp.Schema = schema.Schema{
40 | // This description is used by the documentation generator and the language server.
41 | MarkdownDescription: "{{.Description}}",
42 | Attributes: map[string]schema.Attribute{
43 | {{.SchemaAttributes}}
44 | "rendered_json": schema.StringAttribute{
45 | Computed: true,
46 | MarkdownDescription: "This datasource rendered as JSON",
47 | },
48 | },
49 | }
50 | }
51 |
52 | func (d *{{.StructName}}) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {}
53 |
54 | func (d *{{.StructName}}) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
55 | var data {{.StructName}}Model
56 |
57 | // Read Terraform configuration data into the model
58 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
59 |
60 | if resp.Diagnostics.HasError() {
61 | return
62 | }
63 |
64 | JSONConfig, err := json.Marshal(data)
65 | if err != nil {
66 | resp.Diagnostics.AddError("JSON marshalling error", err.Error())
67 | return
68 | }
69 |
70 | {{ if eq .StructName "CoreDashboardDataSource" }}
71 | // fix up the panel Attribute
72 | // Read into a map[string]interface{} and then marshal it back to JSON
73 | // This is a workaround for the fact that the panel attribute should be a list of maps but is a list of json strings
74 | dataMap := make(map[string]interface{})
75 | err = json.Unmarshal(JSONConfig, &dataMap)
76 | if err != nil {
77 | resp.Diagnostics.AddError("error unmarshalling config into Go map", err.Error())
78 | return
79 | }
80 | panels := data.Panels.Elements()
81 | panelsMaps := make([]map[string]interface{}, len(panels))
82 | for i, panel := range panels {
83 | panelMap := make(map[string]interface{})
84 | err = json.Unmarshal([]byte(panel.(types.String).ValueString()), &panelMap)
85 | if err != nil {
86 | resp.Diagnostics.AddError("error unmarshalling panel into go map", err.Error())
87 | return
88 | }
89 | panelsMaps[i] = panelMap
90 | }
91 |
92 | dataMap["panels"] = panelsMaps
93 | JSONConfig, err = json.MarshalIndent(dataMap, "", " ")
94 | if err != nil {
95 | resp.Diagnostics.AddError("error marshalling go map into json", err.Error())
96 | return
97 | }
98 | {{ end }}
99 |
100 | {{ if startsWith .StructName "Panel" }}
101 | // fix up the targets Attribute
102 | // Read into a map[string]interface{} and then marshal it back to JSON
103 | // This is a workaround for the fact that the targets attribute should be a list of maps but is a list of json strings
104 | dataMap := make(map[string]interface{})
105 | err = json.Unmarshal(JSONConfig, &dataMap)
106 | if err != nil {
107 | resp.Diagnostics.AddError("error unmarshalling config into Go map", err.Error())
108 | return
109 | }
110 | targets := data.Targets.Elements()
111 | targetsMaps := make([]map[string]interface{}, len(targets))
112 | for i, target := range targets {
113 | targetMap := make(map[string]interface{})
114 | err = json.Unmarshal([]byte(target.(types.String).ValueString()), &targetMap)
115 | if err != nil {
116 | resp.Diagnostics.AddError("error unmarshalling target into go map", err.Error())
117 | return
118 | }
119 | targetsMaps[i] = targetMap
120 | }
121 |
122 | dataMap["targets"] = targetsMaps
123 | JSONConfig, err = json.MarshalIndent(dataMap, "", " ")
124 | if err != nil {
125 | resp.Diagnostics.AddError("error marshalling go map into json", err.Error())
126 | return
127 | }
128 | {{ end }}
129 |
130 | // Not sure about that
131 | data.RenderedJSON = types.StringValue(string(JSONConfig))
132 |
133 | // Write logs using the tflog package
134 | // Documentation: https://terraform.io/plugin/log
135 | tflog.Trace(ctx, "read a data source")
136 |
137 | // Save data into Terraform state
138 | resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
139 | }
140 |
--------------------------------------------------------------------------------
/internal/provider/datasource_query_parca_gen.go:
--------------------------------------------------------------------------------
1 | // Code generated - EDITING IS FUTILE. DO NOT EDIT.
2 | //
3 | // Generated by pipeline:
4 | // terraform
5 | // Using jennies:
6 | // TerraformDataSourceJenny
7 | // ComposableLatestMajorsOrXJenny
8 | //
9 | // Run 'go generate ./' from repository root to regenerate.
10 |
11 | package provider
12 |
13 | import (
14 | "context"
15 | "encoding/json"
16 |
17 | "github.com/hashicorp/terraform-plugin-framework/attr"
18 | "github.com/hashicorp/terraform-plugin-framework/datasource"
19 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema"
20 | "github.com/hashicorp/terraform-plugin-framework/diag"
21 | "github.com/hashicorp/terraform-plugin-framework/types"
22 | "github.com/hashicorp/terraform-plugin-log/tflog"
23 | )
24 |
25 | // Ensure that the imports are used to avoid compiler errors.
26 | var _ attr.Value
27 | var _ diag.Diagnostic
28 |
29 | // Ensure provider defined types fully satisfy framework interfaces.
30 | var (
31 | _ datasource.DataSource = &QueryParcaDataSource{}
32 | _ datasource.DataSourceWithConfigure = &QueryParcaDataSource{}
33 | )
34 |
35 | func NewQueryParcaDataSource() datasource.DataSource {
36 | return &QueryParcaDataSource{}
37 | }
38 |
39 | // QueryParcaDataSource defines the data source implementation.
40 | type QueryParcaDataSource struct{}
41 |
42 | type QueryParcaDataSourceModel struct {
43 | RenderedJSON types.String `tfsdk:"rendered_json"`
44 | LabelSelector types.String `tfsdk:"label_selector"`
45 | ProfileTypeId types.String `tfsdk:"profile_type_id"`
46 | RefId types.String `tfsdk:"ref_id"`
47 | Hide types.Bool `tfsdk:"hide"`
48 | QueryType types.String `tfsdk:"query_type"`
49 | }
50 |
51 | func (m QueryParcaDataSourceModel) MarshalJSON() ([]byte, error) {
52 | type jsonQueryParcaDataSourceModel struct {
53 | LabelSelector string `json:"labelSelector"`
54 | ProfileTypeId string `json:"profileTypeId"`
55 | RefId string `json:"refId"`
56 | Hide *bool `json:"hide,omitempty"`
57 | QueryType *string `json:"queryType,omitempty"`
58 | }
59 |
60 | m = m.ApplyDefaults()
61 | attr_labelselector := m.LabelSelector.ValueString()
62 | attr_profiletypeid := m.ProfileTypeId.ValueString()
63 | attr_refid := m.RefId.ValueString()
64 | attr_hide := m.Hide.ValueBoolPointer()
65 | attr_querytype := m.QueryType.ValueStringPointer()
66 |
67 | model := &jsonQueryParcaDataSourceModel{
68 | LabelSelector: attr_labelselector,
69 | ProfileTypeId: attr_profiletypeid,
70 | RefId: attr_refid,
71 | Hide: attr_hide,
72 | QueryType: attr_querytype,
73 | }
74 | return json.Marshal(model)
75 | }
76 |
77 | func (m QueryParcaDataSourceModel) ApplyDefaults() QueryParcaDataSourceModel {
78 | if m.LabelSelector.IsNull() {
79 | m.LabelSelector = types.StringValue(`{}`)
80 | }
81 | return m
82 | }
83 |
84 | func (d *QueryParcaDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
85 | resp.TypeName = req.ProviderTypeName + "_query_parca"
86 | }
87 |
88 | func (d *QueryParcaDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
89 | resp.Schema = schema.Schema{
90 | // This description is used by the documentation generator and the language server.
91 | MarkdownDescription: "",
92 | Attributes: map[string]schema.Attribute{
93 | "label_selector": schema.StringAttribute{
94 | MarkdownDescription: `Specifies the query label selectors. Defaults to "{}".`,
95 | Computed: true,
96 | Optional: true,
97 | Required: false,
98 | },
99 | "profile_type_id": schema.StringAttribute{
100 | MarkdownDescription: `Specifies the type of profile to query.`,
101 | Computed: false,
102 | Optional: false,
103 | Required: true,
104 | },
105 | "ref_id": schema.StringAttribute{
106 | MarkdownDescription: `A unique identifier for the query within the list of targets.
107 | In server side expressions, the refId is used as a variable name to identify results.
108 | By default, the UI will assign A->Z; however setting meaningful names may be useful.`,
109 | Computed: false,
110 | Optional: false,
111 | Required: true,
112 | },
113 | "hide": schema.BoolAttribute{
114 | MarkdownDescription: `true if query is disabled (ie should not be returned to the dashboard)
115 | Note this does not always imply that the query should not be executed since
116 | the results from a hidden query may be used as the input to other queries (SSE etc)`,
117 | Computed: false,
118 | Optional: true,
119 | Required: false,
120 | },
121 | "query_type": schema.StringAttribute{
122 | MarkdownDescription: `Specify the query flavor
123 | TODO make this required and give it a default`,
124 | Computed: false,
125 | Optional: true,
126 | Required: false,
127 | },
128 |
129 | "rendered_json": schema.StringAttribute{
130 | Computed: true,
131 | MarkdownDescription: "This datasource rendered as JSON",
132 | },
133 | },
134 | }
135 | }
136 |
137 | func (d *QueryParcaDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
138 | }
139 |
140 | func (d *QueryParcaDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
141 | var data QueryParcaDataSourceModel
142 |
143 | // Read Terraform configuration data into the model
144 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
145 |
146 | if resp.Diagnostics.HasError() {
147 | return
148 | }
149 |
150 | JSONConfig, err := json.Marshal(data)
151 | if err != nil {
152 | resp.Diagnostics.AddError("JSON marshalling error", err.Error())
153 | return
154 | }
155 |
156 | // Not sure about that
157 | data.RenderedJSON = types.StringValue(string(JSONConfig))
158 |
159 | // Write logs using the tflog package
160 | // Documentation: https://terraform.io/plugin/log
161 | tflog.Trace(ctx, "read a data source")
162 |
163 | // Save data into Terraform state
164 | resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
165 | }
166 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/grafana/terraform-provider-schemas
2 |
3 | go 1.20
4 |
5 | require (
6 | github.com/grafana/thema v0.0.0-20230615161902-b6e21996aef8
7 | github.com/hashicorp/terraform-plugin-docs v0.16.0
8 | github.com/hashicorp/terraform-plugin-framework v1.4.2
9 | github.com/hashicorp/terraform-plugin-log v0.9.0
10 | )
11 |
12 | require (
13 | github.com/Masterminds/goutils v1.1.1 // indirect
14 | github.com/Masterminds/semver/v3 v3.1.1 // indirect
15 | github.com/Masterminds/sprig/v3 v3.2.2 // indirect
16 | github.com/ProtonMail/go-crypto v0.0.0-20230426101702-58e86b294756 // indirect
17 | github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
18 | github.com/armon/go-radix v1.0.0 // indirect
19 | github.com/bgentry/speakeasy v0.1.0 // indirect
20 | github.com/cloudflare/circl v1.3.3 // indirect
21 | github.com/cockroachdb/errors v1.9.1 // indirect
22 | github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f // indirect
23 | github.com/cockroachdb/redact v1.1.3 // indirect
24 | github.com/dave/dst v0.27.2 // indirect
25 | github.com/getkin/kin-openapi v0.115.0 // indirect
26 | github.com/getsentry/sentry-go v0.12.0 // indirect
27 | github.com/go-logr/logr v1.2.4 // indirect
28 | github.com/go-openapi/jsonpointer v0.19.6 // indirect
29 | github.com/go-openapi/swag v0.22.3 // indirect
30 | github.com/google/gofuzz v1.2.0 // indirect
31 | github.com/google/wire v0.5.0 // indirect
32 | github.com/grafana/cuetsy v0.1.9 // indirect
33 | github.com/hashicorp/go-checkpoint v0.5.0 // indirect
34 | github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
35 | github.com/hashicorp/go-version v1.6.0 // indirect
36 | github.com/hashicorp/hc-install v0.5.2 // indirect
37 | github.com/hashicorp/terraform-exec v0.18.1 // indirect
38 | github.com/hashicorp/terraform-json v0.17.1 // indirect
39 | github.com/hashicorp/terraform-plugin-go v0.19.0 // indirect
40 | github.com/huandu/xstrings v1.3.2 // indirect
41 | github.com/imdario/mergo v0.3.13 // indirect
42 | github.com/invopop/yaml v0.2.0 // indirect
43 | github.com/josharian/intern v1.0.0 // indirect
44 | github.com/json-iterator/go v1.1.12 // indirect
45 | github.com/labstack/echo/v4 v4.10.2 // indirect
46 | github.com/labstack/gommon v0.4.0 // indirect
47 | github.com/mailru/easyjson v0.7.7 // indirect
48 | github.com/mattn/go-runewidth v0.0.14 // indirect
49 | github.com/mitchellh/cli v1.1.5 // indirect
50 | github.com/mitchellh/copystructure v1.2.0 // indirect
51 | github.com/mitchellh/reflectwalk v1.0.2 // indirect
52 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
53 | github.com/modern-go/reflect2 v1.0.2 // indirect
54 | github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
55 | github.com/olekukonko/tablewriter v0.0.5 // indirect
56 | github.com/perimeterx/marshmallow v1.1.4 // indirect
57 | github.com/posener/complete v1.2.3 // indirect
58 | github.com/rivo/uniseg v0.4.4 // indirect
59 | github.com/russross/blackfriday v1.6.0 // indirect
60 | github.com/shopspring/decimal v1.3.1 // indirect
61 | github.com/spf13/cast v1.5.0 // indirect
62 | github.com/valyala/bytebufferpool v1.0.0 // indirect
63 | github.com/valyala/fasttemplate v1.2.2 // indirect
64 | github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
65 | github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
66 | github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
67 | github.com/xlab/treeprint v1.2.0 // indirect
68 | github.com/zclconf/go-cty v1.13.2 // indirect
69 | golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect
70 | google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect
71 | gopkg.in/inf.v0 v0.9.1 // indirect
72 | gopkg.in/yaml.v2 v2.4.0 // indirect
73 | k8s.io/apimachinery v0.27.2 // indirect
74 | k8s.io/klog/v2 v2.100.1 // indirect
75 | k8s.io/utils v0.0.0-20230505201702-9f6742963106 // indirect
76 | sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
77 | sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
78 | )
79 |
80 | require (
81 | github.com/google/go-cmp v0.6.0 // indirect
82 | github.com/grafana/grafana v1.9.2-0.20230706143427-a8d2a9ae2ba1
83 | github.com/yalue/merged_fs v1.2.3 // indirect
84 | golang.org/x/sync v0.4.0 // indirect
85 | )
86 |
87 | require (
88 | cuelang.org/go v0.6.0-0.dev
89 | github.com/cockroachdb/apd/v2 v2.0.2 // indirect
90 | github.com/emicklei/proto v1.11.2 // indirect
91 | github.com/fatih/color v1.15.0 // indirect
92 | github.com/gogo/protobuf v1.3.2 // indirect
93 | github.com/golang/protobuf v1.5.3 // indirect
94 | github.com/google/uuid v1.3.0 // indirect
95 | github.com/grafana/codejen v0.0.4-0.20221122220907-a5e7cc5407b3
96 | github.com/grafana/kindsys v0.0.0-20230508162304-452481b63482
97 | github.com/hashicorp/errwrap v1.1.0 // indirect
98 | github.com/hashicorp/go-hclog v1.5.0 // indirect
99 | github.com/hashicorp/go-multierror v1.1.1 // indirect
100 | github.com/hashicorp/go-plugin v1.5.1 // indirect
101 | github.com/hashicorp/go-uuid v1.0.3 // indirect
102 | github.com/hashicorp/terraform-registry-address v0.2.2 // indirect
103 | github.com/hashicorp/terraform-svchost v0.1.1 // indirect
104 | github.com/hashicorp/yamux v0.1.1 // indirect
105 | github.com/kr/pretty v0.3.1 // indirect
106 | github.com/kr/text v0.2.0 // indirect
107 | github.com/mattn/go-colorable v0.1.13 // indirect
108 | github.com/mattn/go-isatty v0.0.19 // indirect
109 | github.com/mitchellh/go-testing-interface v1.14.1 // indirect
110 | github.com/mitchellh/go-wordwrap v1.0.1 // indirect
111 | github.com/mpvl/unique v0.0.0-20150818121801-cbe035fff7de // indirect
112 | github.com/oklog/run v1.1.0 // indirect
113 | github.com/pkg/errors v0.9.1 // indirect
114 | github.com/protocolbuffers/txtpbfmt v0.0.0-20230412060525-fa9f017c0ded // indirect
115 | github.com/rogpeppe/go-internal v1.10.0 // indirect
116 | golang.org/x/crypto v0.14.0 // indirect
117 | golang.org/x/mod v0.13.0 // indirect
118 | golang.org/x/net v0.17.0 // indirect
119 | golang.org/x/sys v0.13.0 // indirect
120 | golang.org/x/text v0.13.0
121 | golang.org/x/tools v0.14.0
122 | google.golang.org/grpc v1.57.0 // indirect
123 | google.golang.org/protobuf v1.31.0 // indirect
124 | gopkg.in/yaml.v3 v3.0.1 // indirect
125 | )
126 |
--------------------------------------------------------------------------------
/gen/terraform/cuetf/types/model.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "fmt"
5 | "strings"
6 |
7 | "cuelang.org/go/cue"
8 | "github.com/grafana/terraform-provider-schemas/gen/terraform/cuetf/internal/utils"
9 | )
10 |
11 | type Model struct {
12 | Name string
13 | IsDisjunction bool
14 | Nodes []Node
15 | Nested bool
16 | }
17 |
18 | // terraformModel generates the Terraform SDK model.
19 | func (s *Model) terraformModel() string {
20 | fields := make([]string, 0)
21 | if !s.Nested {
22 | fields = append(fields, "RenderedJSON types.String `tfsdk:\"rendered_json\"`")
23 | }
24 |
25 | for _, node := range s.Nodes {
26 | if !node.IsGenerated() {
27 | continue
28 | }
29 | fields = append(fields, node.TerraformModelField(s.Name))
30 | }
31 |
32 | return fmt.Sprintf(`type %s struct {
33 | %s
34 | }
35 | `, s.Name, strings.Join(fields, "\n"))
36 | }
37 |
38 | // jsonModel generates the JSON model used to convert the Terraform SDK model to JSON.
39 | func (s *Model) jsonModel() string {
40 | fields := make([]string, 0)
41 | for _, node := range s.Nodes {
42 | if !node.IsGenerated() {
43 | continue
44 | }
45 | fields = append(fields, node.JSONModelField())
46 | }
47 |
48 | return fmt.Sprintf(`type json%s struct {
49 | %s
50 | }
51 | `, s.Name, strings.Join(fields, "\n"))
52 | }
53 |
54 | // generateToJSONFunction generates a function that converts the Terraform SDK model to the JSON model representation.
55 | func (s *Model) generateToJSONFunction() string {
56 | b := strings.Builder{}
57 |
58 | for _, node := range s.Nodes {
59 | if len(node.DisjunctionKinds) > 0 {
60 | b.WriteString(s.generateGetAttrFunction(node))
61 | }
62 | }
63 |
64 | fmt.Fprintf(&b, "func (m %s) MarshalJSON() ([]byte, error) {\n", s.Name)
65 | if s.IsDisjunction {
66 | fmt.Fprintf(&b, "var json_%s interface{}\n", s.Name)
67 | } else {
68 | b.WriteString(s.jsonModel() + "\n")
69 | }
70 | b.WriteString("m = m.ApplyDefaults()\n")
71 |
72 | structLines := make([]string, 0)
73 | for _, node := range s.Nodes {
74 | if !node.IsGenerated() {
75 | continue
76 | }
77 |
78 | fieldName := utils.ToCamelCase(node.Name)
79 | varName := "attr_" + strings.ToLower(node.Name)
80 | if s.IsDisjunction {
81 | varName = "json_" + s.Name
82 | }
83 | funcString := node.terraformFunc()
84 |
85 | if node.Kind == cue.ListKind {
86 | subType := node.SubTerraformType()
87 | subTypeGolang := node.subGolangType()
88 | subTypeFunc := node.subTerraformFunc()
89 | if subType != "" {
90 | fmt.Fprintf(&b, " %s := []%s{}\n", varName, subTypeGolang)
91 | fmt.Fprintf(&b, " for _, v := range m.%s.Elements() {\n", fieldName)
92 | fmt.Fprintf(&b, " %s = append(%s, v.(types.%s).%s)\n", varName, varName, subType, subTypeFunc)
93 | b.WriteString(" }\n")
94 | } else if node.SubKind == cue.StructKind {
95 | fmt.Fprintf(&b, " %s := []interface{}{}\n", varName)
96 | fmt.Fprintf(&b, " for _, v := range m.%s {\n", fieldName)
97 | fmt.Fprintf(&b, " %s = append(%s, v)\n", varName, varName)
98 | b.WriteString(" }\n")
99 | }
100 | } else if node.Kind == cue.StructKind {
101 | if !s.IsDisjunction {
102 | fmt.Fprintf(&b, " var %s interface{}\n", varName)
103 | }
104 | if node.Optional {
105 | fmt.Fprintf(&b, " if m.%s != nil {\n", fieldName)
106 | fmt.Fprintf(&b, " %s = m.%s\n", varName, fieldName)
107 | b.WriteString(" }\n")
108 | } else {
109 | fmt.Fprintf(&b, " %s = m.%s\n", varName, fieldName)
110 | }
111 | } else if len(node.DisjunctionKinds) > 0 {
112 | fmt.Fprintf(&b, " %s := m.GetAttr%s()\n", varName, fieldName)
113 | } else if funcString != "" {
114 | fmt.Fprintf(&b, "%s := m.%s.%s\n", varName, fieldName, funcString)
115 | }
116 |
117 | structLines = append(structLines, fmt.Sprintf(" %s: %s,\n", fieldName, varName))
118 | }
119 |
120 | if s.IsDisjunction {
121 | fmt.Fprintf(&b, `
122 |
123 | return json.Marshal(json_%s)
124 | }
125 |
126 | `, s.Name)
127 | } else {
128 | fmt.Fprintf(&b, `
129 |
130 | model := &json%s {
131 | %s
132 | }
133 | return json.Marshal(model)
134 | }
135 |
136 | `, s.Name, strings.Join(structLines, ""))
137 | }
138 |
139 | return b.String()
140 | }
141 |
142 | func (s *Model) generateGetAttrFunction(node Node) string {
143 | b := strings.Builder{}
144 | attrName := utils.ToCamelCase(node.Name)
145 |
146 | fmt.Fprintf(&b, "func (m %s) GetAttr%s() interface{} {\n", s.Name, attrName)
147 | b.WriteString("var attr interface{}\nvar err error\n\n")
148 |
149 | for _, kind := range node.DisjunctionKinds {
150 | switch kind {
151 | case cue.StructKind, cue.ListKind:
152 | fmt.Fprintf(&b, "err = json.Unmarshal([]byte(m.%s.ValueString()), &attr)", attrName)
153 | case cue.BoolKind:
154 | fmt.Fprintf(&b, "attr, err = strconv.ParseBool(m.%s.ValueString())", attrName)
155 | case cue.IntKind:
156 | fmt.Fprintf(&b, "attr, err = strconv.ParseInt(m.%s.ValueString(), 10, 64)", attrName)
157 | case cue.NumberKind, cue.FloatKind:
158 | fmt.Fprintf(&b, "attr, err = strconv.ParseFloat(m.%s.ValueString(), 64)", attrName)
159 | case cue.StringKind:
160 | continue
161 | }
162 |
163 | b.WriteString(`
164 | if err == nil {
165 | return attr
166 | }
167 | `)
168 | }
169 | fmt.Fprintf(&b, `
170 | return m.%s.ValueString()
171 | }
172 |
173 | `, attrName)
174 |
175 | return b.String()
176 | }
177 |
178 | func (s *Model) generateDefaultsFunction() string {
179 | defaults := make([]string, 0)
180 | for _, node := range s.Nodes {
181 | kind := node.TerraformType()
182 |
183 | if kind != "" && node.Default != "" {
184 | defaults = append(defaults, fmt.Sprintf(`if m.%s.IsNull() {
185 | m.%s = types.%sValue(%s)
186 | }`, utils.ToCamelCase(node.Name), utils.ToCamelCase(node.Name), kind, node.Default))
187 | }
188 |
189 | if node.Kind == cue.ListKind && node.SubTerraformType() != "" {
190 | defaults = append(defaults, fmt.Sprintf(`if len(m.%s.Elements()) == 0 {
191 | m.%s, _ = types.ListValue(types.%sType, []attr.Value{})
192 | }`, utils.ToCamelCase(node.Name), utils.ToCamelCase(node.Name), node.SubTerraformType()))
193 | }
194 |
195 | }
196 |
197 | return fmt.Sprintf(`func (m %[1]s) ApplyDefaults() %[1]s {
198 | %s
199 | return m
200 | }
201 |
202 | `, s.Name, strings.Join(defaults, "\n"))
203 | }
204 |
205 | func (s *Model) Generate() string {
206 | b := strings.Builder{}
207 | for _, node := range s.Nodes {
208 | if node.Kind == cue.StructKind || node.Kind == cue.ListKind && node.SubKind == cue.StructKind {
209 | nestedModel := Model{
210 | Name: s.Name + "_" + utils.Title(node.Name),
211 | IsDisjunction: node.IsDisjunction,
212 | Nodes: node.Children,
213 | Nested: true,
214 | }
215 | b.WriteString(nestedModel.Generate())
216 | }
217 | }
218 |
219 | b.WriteString(s.terraformModel())
220 | b.WriteString(s.generateToJSONFunction())
221 | b.WriteString(s.generateDefaultsFunction())
222 |
223 | return b.String()
224 | }
225 |
--------------------------------------------------------------------------------
/gen/terraform/cuetf/internal/nodes.go:
--------------------------------------------------------------------------------
1 | package internal
2 |
3 | import (
4 | "errors"
5 | "fmt"
6 | "regexp"
7 | "strings"
8 |
9 | "cuelang.org/go/cue"
10 | "cuelang.org/go/cue/ast"
11 | "github.com/grafana/terraform-provider-schemas/gen/terraform/cuetf/types"
12 | )
13 |
14 | func GetAllNodes(val cue.Value) ([]types.Node, error) {
15 | if err := val.Validate(); err != nil {
16 | return nil, fmt.Errorf("error validating value: %w", err)
17 | }
18 |
19 | iter, err := val.Fields(
20 | cue.Definitions(false), // Should we do something with those?
21 | cue.Optional(true),
22 | )
23 | if err != nil {
24 | return nil, fmt.Errorf("error retrieving value fields: %w", err)
25 | }
26 |
27 | nodes := make([]types.Node, 0)
28 | for iter.Next() {
29 | if iter.Selector().String() == "id" {
30 | // id is a field generated by the Grafana server and should not be included in the schema
31 | continue
32 | }
33 |
34 | node, err := GetSingleNode(iter.Selector().String(), iter.Value(), iter.IsOptional())
35 | if err != nil {
36 | return nil, err
37 | }
38 |
39 | if node != nil {
40 | nodes = append(nodes, *node)
41 | }
42 | }
43 |
44 | return nodes, nil
45 | }
46 |
47 | func GetSingleNode(name string, val cue.Value, optional bool) (*types.Node, error) {
48 | // TODO: fixme
49 | if name == "reducer" {
50 | return nil, nil
51 | }
52 |
53 | node := types.Node{
54 | Name: name,
55 | Kind: val.IncompleteKind(),
56 | // Structs should be optional if we want to set nested defaults
57 | Optional: optional || val.IncompleteKind() == cue.StructKind,
58 | Default: getDefault(val),
59 | Doc: formatDoc(val.Doc()),
60 | }
61 |
62 | val = cue.Dereference(val)
63 | op, args := val.Expr()
64 | if op == cue.OrOp {
65 | err := handleDisjunction(&node, args)
66 | return &node, err
67 | }
68 |
69 | switch node.Kind {
70 | case cue.ListKind:
71 | err := handleList(&node, val)
72 | if err != nil {
73 | return nil, err
74 | }
75 | case cue.StructKind:
76 | // Checks [string]something only.
77 | // It skips structs like {...} (cue.TopKind) to avoid undesired results.
78 | v := val.LookupPath(cue.MakePath(cue.AnyString))
79 | if v.Exists() && v.IncompleteKind() != cue.TopKind {
80 | val = v
81 | node.IsMap = true
82 | }
83 |
84 | children, err := GetAllNodes(val.Value())
85 | if err != nil {
86 | return nil, err
87 | }
88 |
89 | node.Children = children
90 | for i := range node.Children {
91 | node.Children[i].Parent = &node
92 | }
93 | }
94 |
95 | return &node, nil
96 | }
97 |
98 | func handleList(node *types.Node, val cue.Value) error {
99 | node.Optional = true
100 |
101 | // TODO: fixme
102 | // Using a string type to allow composition of panel datasources
103 | // Doesn't seem possible to have an arbitrary map type here
104 | if node.Name == "panels" || node.Name == "targets" {
105 | node.SubKind = cue.StringKind
106 | return nil
107 | }
108 |
109 | // From cuetsy:
110 | // If the default (all lists have a default, usually self, ugh) differs from the
111 | // input list, peel it off. Otherwise our AnyIndex lookup may end up getting
112 | // sent on the wrong path.
113 | defv, _ := val.Default()
114 | if !defv.Equals(val) {
115 | _, v := val.Expr()
116 | val = v[0]
117 | }
118 |
119 | e := val.LookupPath(cue.MakePath(cue.AnyIndex))
120 | if !e.Exists() {
121 | return errors.New("unreachable - open list must have a type")
122 | }
123 |
124 | e = cue.Dereference(e)
125 | op, args := e.Expr()
126 | if op == cue.OrOp {
127 | return handleDisjunction(node, args)
128 | }
129 |
130 | node.SubKind = e.IncompleteKind()
131 | switch node.SubKind {
132 | case cue.StructKind:
133 | children, err := GetAllNodes(e)
134 | if err != nil {
135 | return err
136 | }
137 |
138 | node.Children = children
139 | for i := range node.Children {
140 | node.Children[i].Parent = node
141 | }
142 | case cue.ListKind:
143 | // TODO - handle list in list
144 | case cue.TopKind:
145 | // TODO - handle open lists ([...])
146 | }
147 |
148 | return nil
149 | }
150 |
151 | func handleDisjunction(node *types.Node, vals []cue.Value) error {
152 | children := make([]types.Node, 0)
153 | disjuncts := make([]cue.Value, 0)
154 |
155 | isComplex := false
156 | for _, val := range vals {
157 | isStructOrList := val.IncompleteKind() == cue.StructKind || val.IncompleteKind() == cue.ListKind
158 | if isStructOrList || !containsKind(disjuncts, val.IncompleteKind()) {
159 | disjuncts = append(disjuncts, val)
160 | }
161 |
162 | if isStructOrList {
163 | isComplex = true
164 | }
165 | }
166 |
167 | if len(disjuncts) <= 1 && !isComplex {
168 | return nil
169 | }
170 |
171 | if !isComplex || containsKind(disjuncts, cue.StringKind) {
172 | node.Kind = cue.StringKind
173 | for _, d := range disjuncts {
174 | node.DisjunctionKinds = append(node.DisjunctionKinds, d.IncompleteKind())
175 | }
176 | if isComplex {
177 | node.Doc = "JSON-encoded string. " + node.Doc
178 | }
179 | return nil
180 | }
181 |
182 | for _, val := range disjuncts {
183 | node.SubKind = val.IncompleteKind()
184 |
185 | _, p := val.ReferencePath()
186 | arr := strings.Split(p.String(), ".")
187 | name := strings.ReplaceAll(arr[len(arr)-1], "#", "")
188 | // TODO - currently this catches setting a default object
189 | if name == "" {
190 | continue
191 | }
192 |
193 | child, err := GetSingleNode(name, val, true)
194 | if err != nil {
195 | return err
196 | }
197 | child.Parent = node
198 |
199 | children = append(children, *child)
200 | }
201 | node.IsDisjunction = true
202 | node.Children = children
203 |
204 | return nil
205 | }
206 |
207 | func containsKind(values []cue.Value, kind cue.Kind) bool {
208 | for _, v := range values {
209 | if v.IncompleteKind() == kind {
210 | return true
211 | }
212 | }
213 | return false
214 | }
215 |
216 | func getDefault(v cue.Value) string {
217 | _, ok := v.Default()
218 | if !ok {
219 | return ""
220 | }
221 |
222 | switch v.IncompleteKind() {
223 | case cue.StringKind:
224 | s, err := v.String()
225 | if err != nil {
226 | return ""
227 | }
228 | return fmt.Sprintf("`%s`", s)
229 | case cue.FloatKind, cue.NumberKind:
230 | f, err := v.Float64()
231 | if err != nil {
232 | return ""
233 | }
234 | return fmt.Sprintf("%f", f)
235 | case cue.IntKind:
236 | i, err := v.Int64()
237 | if err != nil {
238 | return ""
239 | }
240 | return fmt.Sprintf("%d", i)
241 | case cue.BoolKind:
242 | b, err := v.Bool()
243 | if err != nil {
244 | return ""
245 | }
246 | return fmt.Sprintf("%t", b)
247 | default:
248 | return ""
249 | }
250 | }
251 |
252 | func formatDoc(comments []*ast.CommentGroup) string {
253 | result := ""
254 | for _, comment := range comments {
255 | result += comment.Text()
256 | }
257 |
258 | result = strings.ReplaceAll(result, "`", "")
259 |
260 | reg := regexp.MustCompile(`{{([^}]*)}}`)
261 | result = reg.ReplaceAllString(result, "` + \"{{`{{${1}}}`}}\" + `")
262 |
263 | return strings.Trim(result, "\n ")
264 | }
265 |
--------------------------------------------------------------------------------
/internal/provider/datasource_query_grafana_pyroscope_gen.go:
--------------------------------------------------------------------------------
1 | // Code generated - EDITING IS FUTILE. DO NOT EDIT.
2 | //
3 | // Generated by pipeline:
4 | // terraform
5 | // Using jennies:
6 | // TerraformDataSourceJenny
7 | // ComposableLatestMajorsOrXJenny
8 | //
9 | // Run 'go generate ./' from repository root to regenerate.
10 |
11 | package provider
12 |
13 | import (
14 | "context"
15 | "encoding/json"
16 |
17 | "github.com/hashicorp/terraform-plugin-framework/attr"
18 | "github.com/hashicorp/terraform-plugin-framework/datasource"
19 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema"
20 | "github.com/hashicorp/terraform-plugin-framework/diag"
21 | "github.com/hashicorp/terraform-plugin-framework/types"
22 | "github.com/hashicorp/terraform-plugin-log/tflog"
23 | )
24 |
25 | // Ensure that the imports are used to avoid compiler errors.
26 | var _ attr.Value
27 | var _ diag.Diagnostic
28 |
29 | // Ensure provider defined types fully satisfy framework interfaces.
30 | var (
31 | _ datasource.DataSource = &QueryGrafanaPyroscopeDataSource{}
32 | _ datasource.DataSourceWithConfigure = &QueryGrafanaPyroscopeDataSource{}
33 | )
34 |
35 | func NewQueryGrafanaPyroscopeDataSource() datasource.DataSource {
36 | return &QueryGrafanaPyroscopeDataSource{}
37 | }
38 |
39 | // QueryGrafanaPyroscopeDataSource defines the data source implementation.
40 | type QueryGrafanaPyroscopeDataSource struct{}
41 |
42 | type QueryGrafanaPyroscopeDataSourceModel struct {
43 | RenderedJSON types.String `tfsdk:"rendered_json"`
44 | LabelSelector types.String `tfsdk:"label_selector"`
45 | ProfileTypeId types.String `tfsdk:"profile_type_id"`
46 | GroupBy types.List `tfsdk:"group_by"`
47 | MaxNodes types.Int64 `tfsdk:"max_nodes"`
48 | RefId types.String `tfsdk:"ref_id"`
49 | Hide types.Bool `tfsdk:"hide"`
50 | QueryType types.String `tfsdk:"query_type"`
51 | }
52 |
53 | func (m QueryGrafanaPyroscopeDataSourceModel) MarshalJSON() ([]byte, error) {
54 | type jsonQueryGrafanaPyroscopeDataSourceModel struct {
55 | LabelSelector string `json:"labelSelector"`
56 | ProfileTypeId string `json:"profileTypeId"`
57 | GroupBy []string `json:"groupBy,omitempty"`
58 | MaxNodes *int64 `json:"maxNodes,omitempty"`
59 | RefId string `json:"refId"`
60 | Hide *bool `json:"hide,omitempty"`
61 | QueryType *string `json:"queryType,omitempty"`
62 | }
63 |
64 | m = m.ApplyDefaults()
65 | attr_labelselector := m.LabelSelector.ValueString()
66 | attr_profiletypeid := m.ProfileTypeId.ValueString()
67 | attr_groupby := []string{}
68 | for _, v := range m.GroupBy.Elements() {
69 | attr_groupby = append(attr_groupby, v.(types.String).ValueString())
70 | }
71 | attr_maxnodes := m.MaxNodes.ValueInt64Pointer()
72 | attr_refid := m.RefId.ValueString()
73 | attr_hide := m.Hide.ValueBoolPointer()
74 | attr_querytype := m.QueryType.ValueStringPointer()
75 |
76 | model := &jsonQueryGrafanaPyroscopeDataSourceModel{
77 | LabelSelector: attr_labelselector,
78 | ProfileTypeId: attr_profiletypeid,
79 | GroupBy: attr_groupby,
80 | MaxNodes: attr_maxnodes,
81 | RefId: attr_refid,
82 | Hide: attr_hide,
83 | QueryType: attr_querytype,
84 | }
85 | return json.Marshal(model)
86 | }
87 |
88 | func (m QueryGrafanaPyroscopeDataSourceModel) ApplyDefaults() QueryGrafanaPyroscopeDataSourceModel {
89 | if m.LabelSelector.IsNull() {
90 | m.LabelSelector = types.StringValue(`{}`)
91 | }
92 | if len(m.GroupBy.Elements()) == 0 {
93 | m.GroupBy, _ = types.ListValue(types.StringType, []attr.Value{})
94 | }
95 | return m
96 | }
97 |
98 | func (d *QueryGrafanaPyroscopeDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
99 | resp.TypeName = req.ProviderTypeName + "_query_grafana_pyroscope"
100 | }
101 |
102 | func (d *QueryGrafanaPyroscopeDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
103 | resp.Schema = schema.Schema{
104 | // This description is used by the documentation generator and the language server.
105 | MarkdownDescription: "",
106 | Attributes: map[string]schema.Attribute{
107 | "label_selector": schema.StringAttribute{
108 | MarkdownDescription: `Specifies the query label selectors. Defaults to "{}".`,
109 | Computed: true,
110 | Optional: true,
111 | Required: false,
112 | },
113 | "profile_type_id": schema.StringAttribute{
114 | MarkdownDescription: `Specifies the type of profile to query.`,
115 | Computed: false,
116 | Optional: false,
117 | Required: true,
118 | },
119 | "group_by": schema.ListAttribute{
120 | MarkdownDescription: `Allows to group the results.`,
121 | Computed: false,
122 | Optional: true,
123 | Required: false,
124 | ElementType: types.StringType,
125 | },
126 | "max_nodes": schema.Int64Attribute{
127 | MarkdownDescription: `Sets the maximum number of nodes in the flamegraph.`,
128 | Computed: false,
129 | Optional: true,
130 | Required: false,
131 | },
132 | "ref_id": schema.StringAttribute{
133 | MarkdownDescription: `A unique identifier for the query within the list of targets.
134 | In server side expressions, the refId is used as a variable name to identify results.
135 | By default, the UI will assign A->Z; however setting meaningful names may be useful.`,
136 | Computed: false,
137 | Optional: false,
138 | Required: true,
139 | },
140 | "hide": schema.BoolAttribute{
141 | MarkdownDescription: `true if query is disabled (ie should not be returned to the dashboard)
142 | Note this does not always imply that the query should not be executed since
143 | the results from a hidden query may be used as the input to other queries (SSE etc)`,
144 | Computed: false,
145 | Optional: true,
146 | Required: false,
147 | },
148 | "query_type": schema.StringAttribute{
149 | MarkdownDescription: `Specify the query flavor
150 | TODO make this required and give it a default`,
151 | Computed: false,
152 | Optional: true,
153 | Required: false,
154 | },
155 |
156 | "rendered_json": schema.StringAttribute{
157 | Computed: true,
158 | MarkdownDescription: "This datasource rendered as JSON",
159 | },
160 | },
161 | }
162 | }
163 |
164 | func (d *QueryGrafanaPyroscopeDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
165 | }
166 |
167 | func (d *QueryGrafanaPyroscopeDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
168 | var data QueryGrafanaPyroscopeDataSourceModel
169 |
170 | // Read Terraform configuration data into the model
171 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
172 |
173 | if resp.Diagnostics.HasError() {
174 | return
175 | }
176 |
177 | JSONConfig, err := json.Marshal(data)
178 | if err != nil {
179 | resp.Diagnostics.AddError("JSON marshalling error", err.Error())
180 | return
181 | }
182 |
183 | // Not sure about that
184 | data.RenderedJSON = types.StringValue(string(JSONConfig))
185 |
186 | // Write logs using the tflog package
187 | // Documentation: https://terraform.io/plugin/log
188 | tflog.Trace(ctx, "read a data source")
189 |
190 | // Save data into Terraform state
191 | resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
192 | }
193 |
--------------------------------------------------------------------------------
/internal/provider/datasource_query_loki_gen.go:
--------------------------------------------------------------------------------
1 | // Code generated - EDITING IS FUTILE. DO NOT EDIT.
2 | //
3 | // Generated by pipeline:
4 | // terraform
5 | // Using jennies:
6 | // TerraformDataSourceJenny
7 | // ComposableLatestMajorsOrXJenny
8 | //
9 | // Run 'go generate ./' from repository root to regenerate.
10 |
11 | package provider
12 |
13 | import (
14 | "context"
15 | "encoding/json"
16 |
17 | "github.com/hashicorp/terraform-plugin-framework/attr"
18 | "github.com/hashicorp/terraform-plugin-framework/datasource"
19 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema"
20 | "github.com/hashicorp/terraform-plugin-framework/diag"
21 | "github.com/hashicorp/terraform-plugin-framework/types"
22 | "github.com/hashicorp/terraform-plugin-log/tflog"
23 | )
24 |
25 | // Ensure that the imports are used to avoid compiler errors.
26 | var _ attr.Value
27 | var _ diag.Diagnostic
28 |
29 | // Ensure provider defined types fully satisfy framework interfaces.
30 | var (
31 | _ datasource.DataSource = &QueryLokiDataSource{}
32 | _ datasource.DataSourceWithConfigure = &QueryLokiDataSource{}
33 | )
34 |
35 | func NewQueryLokiDataSource() datasource.DataSource {
36 | return &QueryLokiDataSource{}
37 | }
38 |
39 | // QueryLokiDataSource defines the data source implementation.
40 | type QueryLokiDataSource struct{}
41 |
42 | type QueryLokiDataSourceModel struct {
43 | RenderedJSON types.String `tfsdk:"rendered_json"`
44 | Expr types.String `tfsdk:"expr"`
45 | LegendFormat types.String `tfsdk:"legend_format"`
46 | MaxLines types.Int64 `tfsdk:"max_lines"`
47 | Resolution types.Int64 `tfsdk:"resolution"`
48 | EditorMode types.String `tfsdk:"editor_mode"`
49 | Range types.Bool `tfsdk:"range"`
50 | Instant types.Bool `tfsdk:"instant"`
51 | Step types.String `tfsdk:"step"`
52 | RefId types.String `tfsdk:"ref_id"`
53 | Hide types.Bool `tfsdk:"hide"`
54 | QueryType types.String `tfsdk:"query_type"`
55 | }
56 |
57 | func (m QueryLokiDataSourceModel) MarshalJSON() ([]byte, error) {
58 | type jsonQueryLokiDataSourceModel struct {
59 | Expr string `json:"expr"`
60 | LegendFormat *string `json:"legendFormat,omitempty"`
61 | MaxLines *int64 `json:"maxLines,omitempty"`
62 | Resolution *int64 `json:"resolution,omitempty"`
63 | EditorMode *string `json:"editorMode,omitempty"`
64 | Range *bool `json:"range,omitempty"`
65 | Instant *bool `json:"instant,omitempty"`
66 | Step *string `json:"step,omitempty"`
67 | RefId string `json:"refId"`
68 | Hide *bool `json:"hide,omitempty"`
69 | QueryType *string `json:"queryType,omitempty"`
70 | }
71 |
72 | m = m.ApplyDefaults()
73 | attr_expr := m.Expr.ValueString()
74 | attr_legendformat := m.LegendFormat.ValueStringPointer()
75 | attr_maxlines := m.MaxLines.ValueInt64Pointer()
76 | attr_resolution := m.Resolution.ValueInt64Pointer()
77 | attr_editormode := m.EditorMode.ValueStringPointer()
78 | attr_range := m.Range.ValueBoolPointer()
79 | attr_instant := m.Instant.ValueBoolPointer()
80 | attr_step := m.Step.ValueStringPointer()
81 | attr_refid := m.RefId.ValueString()
82 | attr_hide := m.Hide.ValueBoolPointer()
83 | attr_querytype := m.QueryType.ValueStringPointer()
84 |
85 | model := &jsonQueryLokiDataSourceModel{
86 | Expr: attr_expr,
87 | LegendFormat: attr_legendformat,
88 | MaxLines: attr_maxlines,
89 | Resolution: attr_resolution,
90 | EditorMode: attr_editormode,
91 | Range: attr_range,
92 | Instant: attr_instant,
93 | Step: attr_step,
94 | RefId: attr_refid,
95 | Hide: attr_hide,
96 | QueryType: attr_querytype,
97 | }
98 | return json.Marshal(model)
99 | }
100 |
101 | func (m QueryLokiDataSourceModel) ApplyDefaults() QueryLokiDataSourceModel {
102 |
103 | return m
104 | }
105 |
106 | func (d *QueryLokiDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
107 | resp.TypeName = req.ProviderTypeName + "_query_loki"
108 | }
109 |
110 | func (d *QueryLokiDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
111 | resp.Schema = schema.Schema{
112 | // This description is used by the documentation generator and the language server.
113 | MarkdownDescription: "",
114 | Attributes: map[string]schema.Attribute{
115 | "expr": schema.StringAttribute{
116 | MarkdownDescription: `The LogQL query.`,
117 | Computed: false,
118 | Optional: false,
119 | Required: true,
120 | },
121 | "legend_format": schema.StringAttribute{
122 | MarkdownDescription: `Used to override the name of the series.`,
123 | Computed: false,
124 | Optional: true,
125 | Required: false,
126 | },
127 | "max_lines": schema.Int64Attribute{
128 | MarkdownDescription: `Used to limit the number of log rows returned.`,
129 | Computed: false,
130 | Optional: true,
131 | Required: false,
132 | },
133 | "resolution": schema.Int64Attribute{
134 | MarkdownDescription: `@deprecated, now use step.`,
135 | Computed: false,
136 | Optional: true,
137 | Required: false,
138 | DeprecationMessage: `Now use step.`,
139 | },
140 | "editor_mode": schema.StringAttribute{
141 | MarkdownDescription: ``,
142 | Computed: false,
143 | Optional: true,
144 | Required: false,
145 | },
146 | "range": schema.BoolAttribute{
147 | MarkdownDescription: `@deprecated, now use queryType.`,
148 | Computed: false,
149 | Optional: true,
150 | Required: false,
151 | DeprecationMessage: `Now use queryType.`,
152 | },
153 | "instant": schema.BoolAttribute{
154 | MarkdownDescription: `@deprecated, now use queryType.`,
155 | Computed: false,
156 | Optional: true,
157 | Required: false,
158 | DeprecationMessage: `Now use queryType.`,
159 | },
160 | "step": schema.StringAttribute{
161 | MarkdownDescription: `Used to set step value for range queries.`,
162 | Computed: false,
163 | Optional: true,
164 | Required: false,
165 | },
166 | "ref_id": schema.StringAttribute{
167 | MarkdownDescription: `A unique identifier for the query within the list of targets.
168 | In server side expressions, the refId is used as a variable name to identify results.
169 | By default, the UI will assign A->Z; however setting meaningful names may be useful.`,
170 | Computed: false,
171 | Optional: false,
172 | Required: true,
173 | },
174 | "hide": schema.BoolAttribute{
175 | MarkdownDescription: `true if query is disabled (ie should not be returned to the dashboard)
176 | Note this does not always imply that the query should not be executed since
177 | the results from a hidden query may be used as the input to other queries (SSE etc)`,
178 | Computed: false,
179 | Optional: true,
180 | Required: false,
181 | },
182 | "query_type": schema.StringAttribute{
183 | MarkdownDescription: `Specify the query flavor
184 | TODO make this required and give it a default`,
185 | Computed: false,
186 | Optional: true,
187 | Required: false,
188 | },
189 |
190 | "rendered_json": schema.StringAttribute{
191 | Computed: true,
192 | MarkdownDescription: "This datasource rendered as JSON",
193 | },
194 | },
195 | }
196 | }
197 |
198 | func (d *QueryLokiDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
199 | }
200 |
201 | func (d *QueryLokiDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
202 | var data QueryLokiDataSourceModel
203 |
204 | // Read Terraform configuration data into the model
205 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
206 |
207 | if resp.Diagnostics.HasError() {
208 | return
209 | }
210 |
211 | JSONConfig, err := json.Marshal(data)
212 | if err != nil {
213 | resp.Diagnostics.AddError("JSON marshalling error", err.Error())
214 | return
215 | }
216 |
217 | // Not sure about that
218 | data.RenderedJSON = types.StringValue(string(JSONConfig))
219 |
220 | // Write logs using the tflog package
221 | // Documentation: https://terraform.io/plugin/log
222 | tflog.Trace(ctx, "read a data source")
223 |
224 | // Save data into Terraform state
225 | resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
226 | }
227 |
--------------------------------------------------------------------------------
/internal/provider/datasource_query_prometheus_gen.go:
--------------------------------------------------------------------------------
1 | // Code generated - EDITING IS FUTILE. DO NOT EDIT.
2 | //
3 | // Generated by pipeline:
4 | // terraform
5 | // Using jennies:
6 | // TerraformDataSourceJenny
7 | // ComposableLatestMajorsOrXJenny
8 | //
9 | // Run 'go generate ./' from repository root to regenerate.
10 |
11 | package provider
12 |
13 | import (
14 | "context"
15 | "encoding/json"
16 |
17 | "github.com/hashicorp/terraform-plugin-framework/attr"
18 | "github.com/hashicorp/terraform-plugin-framework/datasource"
19 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema"
20 | "github.com/hashicorp/terraform-plugin-framework/diag"
21 | "github.com/hashicorp/terraform-plugin-framework/types"
22 | "github.com/hashicorp/terraform-plugin-log/tflog"
23 | )
24 |
25 | // Ensure that the imports are used to avoid compiler errors.
26 | var _ attr.Value
27 | var _ diag.Diagnostic
28 |
29 | // Ensure provider defined types fully satisfy framework interfaces.
30 | var (
31 | _ datasource.DataSource = &QueryPrometheusDataSource{}
32 | _ datasource.DataSourceWithConfigure = &QueryPrometheusDataSource{}
33 | )
34 |
35 | func NewQueryPrometheusDataSource() datasource.DataSource {
36 | return &QueryPrometheusDataSource{}
37 | }
38 |
39 | // QueryPrometheusDataSource defines the data source implementation.
40 | type QueryPrometheusDataSource struct{}
41 |
42 | type QueryPrometheusDataSourceModel struct {
43 | RenderedJSON types.String `tfsdk:"rendered_json"`
44 | Expr types.String `tfsdk:"expr"`
45 | Instant types.Bool `tfsdk:"instant"`
46 | Range types.Bool `tfsdk:"range"`
47 | Exemplar types.Bool `tfsdk:"exemplar"`
48 | EditorMode types.String `tfsdk:"editor_mode"`
49 | Format types.String `tfsdk:"format"`
50 | LegendFormat types.String `tfsdk:"legend_format"`
51 | IntervalFactor types.Float64 `tfsdk:"interval_factor"`
52 | RefId types.String `tfsdk:"ref_id"`
53 | Hide types.Bool `tfsdk:"hide"`
54 | QueryType types.String `tfsdk:"query_type"`
55 | }
56 |
57 | func (m QueryPrometheusDataSourceModel) MarshalJSON() ([]byte, error) {
58 | type jsonQueryPrometheusDataSourceModel struct {
59 | Expr string `json:"expr"`
60 | Instant *bool `json:"instant,omitempty"`
61 | Range *bool `json:"range,omitempty"`
62 | Exemplar *bool `json:"exemplar,omitempty"`
63 | EditorMode *string `json:"editorMode,omitempty"`
64 | Format *string `json:"format,omitempty"`
65 | LegendFormat *string `json:"legendFormat,omitempty"`
66 | IntervalFactor *float64 `json:"intervalFactor,omitempty"`
67 | RefId string `json:"refId"`
68 | Hide *bool `json:"hide,omitempty"`
69 | QueryType *string `json:"queryType,omitempty"`
70 | }
71 |
72 | m = m.ApplyDefaults()
73 | attr_expr := m.Expr.ValueString()
74 | attr_instant := m.Instant.ValueBoolPointer()
75 | attr_range := m.Range.ValueBoolPointer()
76 | attr_exemplar := m.Exemplar.ValueBoolPointer()
77 | attr_editormode := m.EditorMode.ValueStringPointer()
78 | attr_format := m.Format.ValueStringPointer()
79 | attr_legendformat := m.LegendFormat.ValueStringPointer()
80 | attr_intervalfactor := m.IntervalFactor.ValueFloat64Pointer()
81 | attr_refid := m.RefId.ValueString()
82 | attr_hide := m.Hide.ValueBoolPointer()
83 | attr_querytype := m.QueryType.ValueStringPointer()
84 |
85 | model := &jsonQueryPrometheusDataSourceModel{
86 | Expr: attr_expr,
87 | Instant: attr_instant,
88 | Range: attr_range,
89 | Exemplar: attr_exemplar,
90 | EditorMode: attr_editormode,
91 | Format: attr_format,
92 | LegendFormat: attr_legendformat,
93 | IntervalFactor: attr_intervalfactor,
94 | RefId: attr_refid,
95 | Hide: attr_hide,
96 | QueryType: attr_querytype,
97 | }
98 | return json.Marshal(model)
99 | }
100 |
101 | func (m QueryPrometheusDataSourceModel) ApplyDefaults() QueryPrometheusDataSourceModel {
102 |
103 | return m
104 | }
105 |
106 | func (d *QueryPrometheusDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
107 | resp.TypeName = req.ProviderTypeName + "_query_prometheus"
108 | }
109 |
110 | func (d *QueryPrometheusDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
111 | resp.Schema = schema.Schema{
112 | // This description is used by the documentation generator and the language server.
113 | MarkdownDescription: "",
114 | Attributes: map[string]schema.Attribute{
115 | "expr": schema.StringAttribute{
116 | MarkdownDescription: `The actual expression/query that will be evaluated by Prometheus`,
117 | Computed: false,
118 | Optional: false,
119 | Required: true,
120 | },
121 | "instant": schema.BoolAttribute{
122 | MarkdownDescription: `Returns only the latest value that Prometheus has scraped for the requested time series`,
123 | Computed: false,
124 | Optional: true,
125 | Required: false,
126 | },
127 | "range": schema.BoolAttribute{
128 | MarkdownDescription: `Returns a Range vector, comprised of a set of time series containing a range of data points over time for each time series`,
129 | Computed: false,
130 | Optional: true,
131 | Required: false,
132 | },
133 | "exemplar": schema.BoolAttribute{
134 | MarkdownDescription: `Execute an additional query to identify interesting raw samples relevant for the given expr`,
135 | Computed: false,
136 | Optional: true,
137 | Required: false,
138 | },
139 | "editor_mode": schema.StringAttribute{
140 | MarkdownDescription: `Specifies which editor is being used to prepare the query. It can be "code" or "builder"`,
141 | Computed: false,
142 | Optional: true,
143 | Required: false,
144 | },
145 | "format": schema.StringAttribute{
146 | MarkdownDescription: `Query format to determine how to display data points in panel. It can be "time_series", "table", "heatmap"`,
147 | Computed: false,
148 | Optional: true,
149 | Required: false,
150 | },
151 | "legend_format": schema.StringAttribute{
152 | MarkdownDescription: `Series name override or template. Ex. ` + "{{`{{hostname}}`}}" + ` will be replaced with label value for hostname`,
153 | Computed: false,
154 | Optional: true,
155 | Required: false,
156 | },
157 | "interval_factor": schema.Float64Attribute{
158 | MarkdownDescription: `@deprecated Used to specify how many times to divide max data points by. We use max data points under query options
159 | See https://github.com/grafana/grafana/issues/48081`,
160 | Computed: false,
161 | Optional: true,
162 | Required: false,
163 | DeprecationMessage: `Used to specify how many times to divide max data points by. We use max data points under query options
164 | See https://github.com/grafana/grafana/issues/48081`,
165 | },
166 | "ref_id": schema.StringAttribute{
167 | MarkdownDescription: `A unique identifier for the query within the list of targets.
168 | In server side expressions, the refId is used as a variable name to identify results.
169 | By default, the UI will assign A->Z; however setting meaningful names may be useful.`,
170 | Computed: false,
171 | Optional: false,
172 | Required: true,
173 | },
174 | "hide": schema.BoolAttribute{
175 | MarkdownDescription: `true if query is disabled (ie should not be returned to the dashboard)
176 | Note this does not always imply that the query should not be executed since
177 | the results from a hidden query may be used as the input to other queries (SSE etc)`,
178 | Computed: false,
179 | Optional: true,
180 | Required: false,
181 | },
182 | "query_type": schema.StringAttribute{
183 | MarkdownDescription: `Specify the query flavor
184 | TODO make this required and give it a default`,
185 | Computed: false,
186 | Optional: true,
187 | Required: false,
188 | },
189 |
190 | "rendered_json": schema.StringAttribute{
191 | Computed: true,
192 | MarkdownDescription: "This datasource rendered as JSON",
193 | },
194 | },
195 | }
196 | }
197 |
198 | func (d *QueryPrometheusDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
199 | }
200 |
201 | func (d *QueryPrometheusDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
202 | var data QueryPrometheusDataSourceModel
203 |
204 | // Read Terraform configuration data into the model
205 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
206 |
207 | if resp.Diagnostics.HasError() {
208 | return
209 | }
210 |
211 | JSONConfig, err := json.Marshal(data)
212 | if err != nil {
213 | resp.Diagnostics.AddError("JSON marshalling error", err.Error())
214 | return
215 | }
216 |
217 | // Not sure about that
218 | data.RenderedJSON = types.StringValue(string(JSONConfig))
219 |
220 | // Write logs using the tflog package
221 | // Documentation: https://terraform.io/plugin/log
222 | tflog.Trace(ctx, "read a data source")
223 |
224 | // Save data into Terraform state
225 | resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
226 | }
227 |
--------------------------------------------------------------------------------
/gen/terraform/cuetf/datasource_generator.go:
--------------------------------------------------------------------------------
1 | package cuetf
2 |
3 | import (
4 | "bytes"
5 | "errors"
6 | "fmt"
7 | "go/format"
8 | "regexp"
9 | "strings"
10 |
11 | "cuelang.org/go/cue"
12 | "github.com/grafana/terraform-provider-schemas/gen/terraform/cuetf/internal"
13 | "github.com/grafana/terraform-provider-schemas/gen/terraform/cuetf/internal/utils"
14 | "github.com/grafana/terraform-provider-schemas/gen/terraform/cuetf/types"
15 | "github.com/grafana/thema"
16 | )
17 |
18 | // GenerateDataSource takes a cue.Value and generates the corresponding Terraform data source.
19 | func GenerateDataSource(schema thema.Schema) (b []byte, err error) {
20 | value := schema.Underlying().LookupPath(cue.MakePath(cue.Str("schema"), cue.Str("spec")))
21 | if !value.Exists() {
22 | value = schema.Underlying().LookupPath(cue.MakePath(cue.Str("schema")))
23 | }
24 |
25 | nodes, err := internal.GetAllNodes(value)
26 | if err != nil {
27 | return nil, err
28 | }
29 |
30 | if err := extractPanelNodes(schema); err != nil {
31 | return nil, err
32 | }
33 |
34 | linName := schema.Lineage().Name()
35 | if strings.HasPrefix(GetKindName(linName), "Panel") {
36 | // The common schema has an `options` field that is empty and overridden by `panelOptions` in the panel schema
37 | // and a `fieldConfig` field that should contain a `custom` field that contains the panel schema `panelFieldConfig` nodes
38 | // It seems like all other fields in the panel schema should be definitions
39 | var panelOptions *types.Node
40 | var panelFieldConfig *types.Node
41 | for i, node := range nodes {
42 | if node.Name == "Options" {
43 | nodes[i].Name = "options"
44 | panelOptions = &nodes[i]
45 | } else if node.Name == "FieldConfig" {
46 | nodes[i].Name = "custom"
47 | panelFieldConfig = &nodes[i]
48 | }
49 | }
50 |
51 | if len(panelNodes) == 0 {
52 | return nil, errors.New("panel schema not found")
53 | }
54 |
55 | for i, node := range panelNodes {
56 | if node.Name == "options" && panelOptions != nil {
57 | panelNodes[i] = *panelOptions
58 | }
59 |
60 | if node.Name == "fieldConfig" && panelFieldConfig != nil {
61 | for _, n1 := range node.Children {
62 | if n1.Name != "defaults" {
63 | continue
64 | }
65 |
66 | for j, n2 := range n1.Children {
67 | if n2.Name == "custom" {
68 | n1.Children[j] = *panelFieldConfig
69 | }
70 | }
71 | }
72 | }
73 |
74 | // TODO: set it as read-only?
75 | if node.Name == "type" {
76 | panelType := GetPanelType(linName)
77 | node.Default = fmt.Sprintf("`%s`", panelType)
78 | panelNodes[i] = node
79 | }
80 | }
81 |
82 | nodes = panelNodes
83 | }
84 |
85 | schemaAttributes, err := GenerateSchemaAttributes(nodes)
86 | if err != nil {
87 | return nil, err
88 | }
89 |
90 | structName := GetStructName(linName)
91 | model := types.Model{
92 | Name: structName + "Model",
93 | Nodes: nodes,
94 | }
95 |
96 | vars := TVarsDataSource{
97 | Name: GetResourceName(linName),
98 | StructName: structName,
99 | Models: model.Generate(),
100 | SchemaAttributes: schemaAttributes,
101 | }
102 |
103 | buf := new(bytes.Buffer)
104 | if err := tmpls.Lookup("datasource.tmpl").Execute(buf, vars); err != nil {
105 | return nil, fmt.Errorf("failed executing datasource template: %w", err)
106 | }
107 | // return buf.Bytes(), nil
108 |
109 | return format.Source(buf.Bytes())
110 | }
111 |
112 | func GenerateSchemaAttributes(nodes []types.Node) (string, error) {
113 | attributes := make([]string, 0)
114 | for _, node := range nodes {
115 | // TODO: all nodes should be generated
116 | if !node.IsGenerated() {
117 | continue
118 | }
119 |
120 | description := node.Doc
121 | if node.Default != "" {
122 | if description != "" && !strings.HasSuffix(description, ".") {
123 | description += "."
124 | }
125 | description += " Defaults to " + strings.ReplaceAll(node.Default, "`", `"`) + "."
126 | }
127 |
128 | var deprecated string
129 | if strings.Contains(node.Doc, "@deprecated") {
130 | deprecated = deprecationMessage(node.Doc)
131 | }
132 |
133 | vars := TVarsSchemaAttribute{
134 | Name: utils.ToSnakeCase(node.Name),
135 | Description: description,
136 | DeprecationMessage: deprecated,
137 | AttributeType: node.TerraformType(),
138 | Computed: false,
139 | Optional: node.Optional,
140 | }
141 |
142 | if node.Default != "" {
143 | vars.Optional = true
144 | vars.Computed = true
145 | }
146 |
147 | switch node.Kind {
148 | case cue.ListKind:
149 | subType := node.SubTerraformType()
150 | if subType != "" {
151 | // "example_attribute": schema.ListAttribute{
152 | // ElementType: types.StringType,
153 | // // ... other fields ...
154 | // },
155 | vars.AttributeType = "List"
156 | vars.ElementType = fmt.Sprintf("types.%sType", subType)
157 | } else if node.SubKind == cue.StructKind {
158 | // "nested_attribute": schema.ListNestedAttribute{
159 | // NestedObject: schema.NestedAttributeObject{
160 | // Attributes: map[string]schema.Attribute{
161 | // "hello": schema.StringAttribute{
162 | // /* ... */
163 | // },
164 | // },
165 | // },
166 | // },
167 | vars.AttributeType = "ListNested"
168 | nestedObjectAttributes, err := GenerateSchemaAttributes(node.Children)
169 | if err != nil {
170 | return "", fmt.Errorf("error trying to generate nested attributes in list: %s", err)
171 | }
172 | vars.NestedObjectAttributes = nestedObjectAttributes
173 | }
174 | case cue.StructKind:
175 | if node.IsMap {
176 | // "nested_attribute": schema.MapNestedAttribute{
177 | // NestedObject: schema.NestedAttributeObject{
178 | // Attributes: map[string]schema.Attribute{
179 | // "hello": schema.StringAttribute{
180 | // /* ... */
181 | // },
182 | // },
183 | // },
184 | // },
185 | vars.AttributeType = "MapNested"
186 | nestedObjectAttributes, err := GenerateSchemaAttributes(node.Children)
187 | if err != nil {
188 | return "", fmt.Errorf("error trying to generate nested attributes in map: %s", err)
189 | }
190 | vars.NestedObjectAttributes = nestedObjectAttributes
191 | } else {
192 | // "nested_attribute": schema.SingleNestedAttribute{
193 | // Attributes: map[string]schema.Attribute{
194 | // "hello": schema.StringAttribute{
195 | // /* ... */
196 | // },
197 | // },
198 | // },
199 | vars.AttributeType = "SingleNested"
200 | nestedAttributes, err := GenerateSchemaAttributes(node.Children)
201 | if err != nil {
202 | return "", fmt.Errorf("error trying to generate nested attributes in struct: %w", err)
203 | }
204 | vars.NestedAttributes = nestedAttributes
205 |
206 | // Structs should be computed if we want to set nested defaults?
207 | vars.Computed = true
208 | }
209 | }
210 |
211 | buf := new(bytes.Buffer)
212 | if err := tmpls.Lookup("schema_attribute.tmpl").Execute(buf, vars); err != nil {
213 | return "", fmt.Errorf("failed executing datasource template: %w", err)
214 | }
215 |
216 | attributes = append(attributes, buf.String())
217 | }
218 |
219 | return strings.Join(attributes, ""), nil
220 | }
221 |
222 | var deprecatedMatch = regexp.MustCompile(`^\W*@deprecated\W*`)
223 |
224 | func deprecationMessage(str string) string {
225 | deprecated := deprecatedMatch.ReplaceAllString(str, "")
226 | return utils.CapitalizeFirstLetter(deprecated)
227 | }
228 |
229 | var panelNodes []types.Node
230 |
231 | func extractPanelNodes(schema thema.Schema) error {
232 | if schema.Lineage().Name() == "dashboard" {
233 | schemaValue := schema.Underlying().LookupPath(cue.MakePath(cue.Str("schema")))
234 | iter, err := schemaValue.Fields(
235 | cue.Definitions(true),
236 | cue.Optional(false),
237 | cue.Attributes(false),
238 | )
239 | if err != nil {
240 | return err
241 | }
242 | for iter.Next() {
243 | if iter.Selector().String() == "#Panel" {
244 | if panelNodes, err = internal.GetAllNodes(iter.Value()); err != nil {
245 | return err
246 | }
247 | break
248 | }
249 | }
250 | }
251 | return nil
252 | }
253 |
254 | func GetKindName(rawName string) string {
255 | name := rawName
256 | if strings.HasSuffix(name, "PanelCfg") {
257 | name = "Panel" + strings.TrimSuffix(name, "PanelCfg")
258 | } else if strings.HasSuffix(name, "DataQuery") {
259 | name = "Query" + strings.TrimSuffix(name, "DataQuery")
260 | } else {
261 | switch name {
262 | case "accesspolicy":
263 | name = "AccessPolicy"
264 | case "librarypanel":
265 | name = "LibraryPanel"
266 | case "publicdashboard":
267 | name = "PublicDashboard"
268 | case "rolebinding":
269 | name = "RoleBinding"
270 | default:
271 | name = utils.Title(name)
272 | }
273 | name = "Core" + name
274 | }
275 |
276 | return name
277 | }
278 |
279 | // From https://github.com/grafana/grafana/blob/main/pkg/kindsysreport/codegen/report.go#LL283-L299
280 | // used to map names for those plugins that aren't following
281 | // naming conventions, like 'annonlist' which comes from "Annotations list".
282 | var irregularPluginNames = map[string]string{
283 | "alertgroups": "alertGroups",
284 | "annotationslist": "annolist",
285 | "dashboardlist": "dashlist",
286 | "nodegraph": "nodeGraph",
287 | "statetimeline": "state-timeline",
288 | "statushistory": "status-history",
289 | "tableold": "table-old",
290 | }
291 |
292 | // TODO: Better way to get panel type?
293 | func GetPanelType(name string) string {
294 | panelType := strings.ToLower(strings.TrimPrefix(GetKindName(name), "Panel"))
295 |
296 | if name, isIrregular := irregularPluginNames[panelType]; isIrregular {
297 | panelType = name
298 | }
299 |
300 | return panelType
301 | }
302 |
303 | func GetStructName(rawName string) string {
304 | return utils.Title(GetKindName(rawName)) + "DataSource"
305 | }
306 |
307 | func GetResourceName(rawName string) string {
308 | return utils.ToSnakeCase(GetKindName(rawName))
309 | }
310 |
--------------------------------------------------------------------------------
/docs/data-sources/core_dashboard.md:
--------------------------------------------------------------------------------
1 | ---
2 | # generated by https://github.com/hashicorp/terraform-plugin-docs
3 | page_title: "schemas_core_dashboard Data Source - terraform-provider-schemas"
4 | subcategory: ""
5 | description: |-
6 |
7 | ---
8 |
9 | # schemas_core_dashboard (Data Source)
10 |
11 |
12 |
13 |
14 |
15 |
16 | ## Schema
17 |
18 | ### Optional
19 |
20 | - `annotations` (Attributes) Contains the list of annotations that are associated with the dashboard.
21 | Annotations are used to overlay event markers and overlay event tags on graphs.
22 | Grafana comes with a native annotation store and the ability to add annotation events directly from the graph panel or via the HTTP API.
23 | See https://grafana.com/docs/grafana/latest/dashboards/build-dashboards/annotate-visualizations/ (see [below for nested schema](#nestedatt--annotations))
24 | - `description` (String) Description of dashboard.
25 | - `editable` (Boolean) Whether a dashboard is editable or not. Defaults to true.
26 | - `fiscal_year_start_month` (Number) The month that the fiscal year starts on. 0 = January, 11 = December. Defaults to 0.
27 | - `gnet_id` (String) ID of a dashboard imported from the https://grafana.com/grafana/dashboards/ portal
28 | - `graph_tooltip` (Number) Configuration of dashboard cursor sync behavior.
29 | Accepted values are 0 (sync turned off), 1 (shared crosshair), 2 (shared crosshair and tooltip). Defaults to 0.
30 | - `links` (Attributes List) Links with references to other dashboards or external websites. (see [below for nested schema](#nestedatt--links))
31 | - `live_now` (Boolean) When set to true, the dashboard will redraw panels at an interval matching the pixel width.
32 | This will keep data "moving left" regardless of the query refresh rate. This setting helps
33 | avoid dashboards presenting stale live data
34 | - `panels` (List of String) List of dashboard panels
35 | - `refresh` (String) Refresh rate of dashboard. Represented via interval string, e.g. "5s", "1m", "1h", "1d".
36 | - `revision` (Number) This property should only be used in dashboards defined by plugins. It is a quick check
37 | to see if the version has changed since the last time.
38 | - `schema_version` (Number) Version of the JSON schema, incremented each time a Grafana update brings
39 | changes to said schema. Defaults to 36.
40 | - `snapshot` (Attributes) Snapshot options. They are present only if the dashboard is a snapshot. (see [below for nested schema](#nestedatt--snapshot))
41 | - `style` (String) Theme of dashboard.
42 | Default value: dark. Defaults to "dark".
43 | - `tags` (List of String) Tags associated with dashboard.
44 | - `templating` (Attributes) Configured template variables (see [below for nested schema](#nestedatt--templating))
45 | - `time` (Attributes) Time range for dashboard.
46 | Accepted values are relative time strings like {from: 'now-6h', to: 'now'} or absolute time strings like {from: '2020-07-10T08:00:00.000Z', to: '2020-07-10T14:00:00.000Z'}. (see [below for nested schema](#nestedatt--time))
47 | - `timepicker` (Attributes) Configuration of the time picker shown at the top of a dashboard. (see [below for nested schema](#nestedatt--timepicker))
48 | - `timezone` (String) Timezone of dashboard. Accepted values are IANA TZDB zone ID or "browser" or "utc". Defaults to "browser".
49 | - `title` (String) Title of dashboard.
50 | - `uid` (String) Unique dashboard identifier that can be generated by anyone. string (8-40)
51 | - `version` (Number) Version of the dashboard, incremented each time the dashboard is updated.
52 | - `week_start` (String) Day when the week starts. Expressed by the name of the day in lowercase, e.g. "monday".
53 |
54 | ### Read-Only
55 |
56 | - `rendered_json` (String) This datasource rendered as JSON
57 |
58 |
59 | ### Nested Schema for `annotations`
60 |
61 | Optional:
62 |
63 | - `list` (Attributes List) List of annotations (see [below for nested schema](#nestedatt--annotations--list))
64 |
65 |
66 | ### Nested Schema for `annotations.list`
67 |
68 | Required:
69 |
70 | - `icon_color` (String) Color to use for the annotation event markers
71 | - `name` (String) Name of annotation.
72 |
73 | Optional:
74 |
75 | - `datasource` (Attributes) Datasource where the annotations data is (see [below for nested schema](#nestedatt--annotations--list--datasource))
76 | - `enable` (Boolean) When enabled the annotation query is issued with every dashboard refresh. Defaults to true.
77 | - `filter` (Attributes) Filters to apply when fetching annotations (see [below for nested schema](#nestedatt--annotations--list--filter))
78 | - `hide` (Boolean) Annotation queries can be toggled on or off at the top of the dashboard.
79 | When hide is true, the toggle is not shown in the dashboard. Defaults to false.
80 | - `target` (Attributes) TODO.. this should just be a normal query target (see [below for nested schema](#nestedatt--annotations--list--target))
81 | - `type` (String) TODO -- this should not exist here, it is based on the --grafana-- datasource
82 |
83 |
84 | ### Nested Schema for `annotations.list.datasource`
85 |
86 | Optional:
87 |
88 | - `type` (String) The plugin type-id
89 | - `uid` (String) Specific datasource instance
90 |
91 |
92 |
93 | ### Nested Schema for `annotations.list.filter`
94 |
95 | Optional:
96 |
97 | - `exclude` (Boolean) Should the specified panels be included or excluded. Defaults to false.
98 | - `ids` (List of Number) Panel IDs that should be included or excluded
99 |
100 |
101 |
102 | ### Nested Schema for `annotations.list.target`
103 |
104 | Required:
105 |
106 | - `limit` (Number) Only required/valid for the grafana datasource...
107 | but code+tests is already depending on it so hard to change
108 | - `match_any` (Boolean) Only required/valid for the grafana datasource...
109 | but code+tests is already depending on it so hard to change
110 | - `type` (String) Only required/valid for the grafana datasource...
111 | but code+tests is already depending on it so hard to change
112 |
113 | Optional:
114 |
115 | - `tags` (List of String) Only required/valid for the grafana datasource...
116 | but code+tests is already depending on it so hard to change
117 |
118 |
119 |
120 |
121 |
122 | ### Nested Schema for `links`
123 |
124 | Required:
125 |
126 | - `icon` (String) Icon name to be displayed with the link
127 | - `title` (String) Title to display with the link
128 | - `tooltip` (String) Tooltip to display when the user hovers their mouse over it
129 | - `type` (String) Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource)
130 | - `url` (String) Link URL. Only required/valid if the type is link
131 |
132 | Optional:
133 |
134 | - `as_dropdown` (Boolean) If true, all dashboards links will be displayed in a dropdown. If false, all dashboards links will be displayed side by side. Only valid if the type is dashboards. Defaults to false.
135 | - `include_vars` (Boolean) If true, includes current template variables values in the link as query params. Defaults to false.
136 | - `keep_time` (Boolean) If true, includes current time range in the link as query params. Defaults to false.
137 | - `tags` (List of String) List of tags to limit the linked dashboards. If empty, all dashboards will be displayed. Only valid if the type is dashboards
138 | - `target_blank` (Boolean) If true, the link will be opened in a new tab. Defaults to false.
139 |
140 |
141 |
142 | ### Nested Schema for `snapshot`
143 |
144 | Required:
145 |
146 | - `created` (String) Time when the snapshot was created
147 | - `expires` (String) Time when the snapshot expires, default is never to expire
148 | - `external` (Boolean) Is the snapshot saved in an external grafana instance
149 | - `external_url` (String) external url, if snapshot was shared in external grafana instance
150 | - `key` (String) Optional, defined the unique key of the snapshot, required if external is true
151 | - `name` (String) Optional, name of the snapshot
152 | - `org_id` (Number) org id of the snapshot
153 | - `updated` (String) last time when the snapshot was updated
154 | - `user_id` (Number) user id of the snapshot creator
155 |
156 | Optional:
157 |
158 | - `url` (String) url of the snapshot, if snapshot was shared internally
159 |
160 |
161 |
162 | ### Nested Schema for `templating`
163 |
164 | Optional:
165 |
166 | - `list` (Attributes List) List of configured template variables with their saved values along with some other metadata (see [below for nested schema](#nestedatt--templating--list))
167 |
168 |
169 | ### Nested Schema for `templating.list`
170 |
171 | Required:
172 |
173 | - `hide` (Number) Visibility configuration for the variable
174 | - `name` (String) Name of variable
175 | - `type` (String) Type of variable
176 |
177 | Optional:
178 |
179 | - `all_format` (String) Format to use while fetching all values from data source, eg: wildcard, glob, regex, pipe, etc.
180 | - `current` (Attributes) Shows current selected variable text/value on the dashboard (see [below for nested schema](#nestedatt--templating--list--current))
181 | - `datasource` (Attributes) Data source used to fetch values for a variable. It can be defined but null. (see [below for nested schema](#nestedatt--templating--list--datasource))
182 | - `description` (String) Description of variable. It can be defined but null.
183 | - `label` (String) Optional display name
184 | - `multi` (Boolean) Whether multiple values can be selected or not from variable value list. Defaults to false.
185 | - `options` (Attributes List) Options that can be selected for a variable. (see [below for nested schema](#nestedatt--templating--list--options))
186 | - `query` (String) JSON-encoded string. Query used to fetch values for a variable
187 | - `refresh` (Number)
188 | - `skip_url_sync` (Boolean) Whether the variable value should be managed by URL query params or not. Defaults to false.
189 |
190 |
191 | ### Nested Schema for `templating.list.current`
192 |
193 | Required:
194 |
195 | - `text` (String) JSON-encoded string. Text to be displayed for the option
196 | - `value` (String) JSON-encoded string. Value of the option
197 |
198 | Optional:
199 |
200 | - `selected` (Boolean) Whether the option is selected or not
201 |
202 |
203 |
204 | ### Nested Schema for `templating.list.datasource`
205 |
206 | Optional:
207 |
208 | - `type` (String) The plugin type-id
209 | - `uid` (String) Specific datasource instance
210 |
211 |
212 |
213 | ### Nested Schema for `templating.list.options`
214 |
215 | Required:
216 |
217 | - `text` (String) JSON-encoded string. Text to be displayed for the option
218 | - `value` (String) JSON-encoded string. Value of the option
219 |
220 | Optional:
221 |
222 | - `selected` (Boolean) Whether the option is selected or not
223 |
224 |
225 |
226 |
227 |
228 | ### Nested Schema for `time`
229 |
230 | Optional:
231 |
232 | - `from` (String) Defaults to "now-6h".
233 | - `to` (String) Defaults to "now".
234 |
235 |
236 |
237 | ### Nested Schema for `timepicker`
238 |
239 | Optional:
240 |
241 | - `collapse` (Boolean) Whether timepicker is collapsed or not. Has no effect on provisioned dashboard. Defaults to false.
242 | - `enable` (Boolean) Whether timepicker is enabled or not. Has no effect on provisioned dashboard. Defaults to true.
243 | - `hidden` (Boolean) Whether timepicker is visible or not. Defaults to false.
244 | - `refresh_intervals` (List of String) Interval options available in the refresh picker dropdown.
245 | - `time_options` (List of String) Selectable options available in the time picker dropdown. Has no effect on provisioned dashboard.
246 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2021 HashiCorp, Inc.
2 |
3 | Mozilla Public License Version 2.0
4 | ==================================
5 |
6 | 1. Definitions
7 | --------------
8 |
9 | 1.1. "Contributor"
10 | means each individual or legal entity that creates, contributes to
11 | the creation of, or owns Covered Software.
12 |
13 | 1.2. "Contributor Version"
14 | means the combination of the Contributions of others (if any) used
15 | by a Contributor and that particular Contributor's Contribution.
16 |
17 | 1.3. "Contribution"
18 | means Covered Software of a particular Contributor.
19 |
20 | 1.4. "Covered Software"
21 | means Source Code Form to which the initial Contributor has attached
22 | the notice in Exhibit A, the Executable Form of such Source Code
23 | Form, and Modifications of such Source Code Form, in each case
24 | including portions thereof.
25 |
26 | 1.5. "Incompatible With Secondary Licenses"
27 | means
28 |
29 | (a) that the initial Contributor has attached the notice described
30 | in Exhibit B to the Covered Software; or
31 |
32 | (b) that the Covered Software was made available under the terms of
33 | version 1.1 or earlier of the License, but not also under the
34 | terms of a Secondary License.
35 |
36 | 1.6. "Executable Form"
37 | means any form of the work other than Source Code Form.
38 |
39 | 1.7. "Larger Work"
40 | means a work that combines Covered Software with other material, in
41 | a separate file or files, that is not Covered Software.
42 |
43 | 1.8. "License"
44 | means this document.
45 |
46 | 1.9. "Licensable"
47 | means having the right to grant, to the maximum extent possible,
48 | whether at the time of the initial grant or subsequently, any and
49 | all of the rights conveyed by this License.
50 |
51 | 1.10. "Modifications"
52 | means any of the following:
53 |
54 | (a) any file in Source Code Form that results from an addition to,
55 | deletion from, or modification of the contents of Covered
56 | Software; or
57 |
58 | (b) any new file in Source Code Form that contains any Covered
59 | Software.
60 |
61 | 1.11. "Patent Claims" of a Contributor
62 | means any patent claim(s), including without limitation, method,
63 | process, and apparatus claims, in any patent Licensable by such
64 | Contributor that would be infringed, but for the grant of the
65 | License, by the making, using, selling, offering for sale, having
66 | made, import, or transfer of either its Contributions or its
67 | Contributor Version.
68 |
69 | 1.12. "Secondary License"
70 | means either the GNU General Public License, Version 2.0, the GNU
71 | Lesser General Public License, Version 2.1, the GNU Affero General
72 | Public License, Version 3.0, or any later versions of those
73 | licenses.
74 |
75 | 1.13. "Source Code Form"
76 | means the form of the work preferred for making modifications.
77 |
78 | 1.14. "You" (or "Your")
79 | means an individual or a legal entity exercising rights under this
80 | License. For legal entities, "You" includes any entity that
81 | controls, is controlled by, or is under common control with You. For
82 | purposes of this definition, "control" means (a) the power, direct
83 | or indirect, to cause the direction or management of such entity,
84 | whether by contract or otherwise, or (b) ownership of more than
85 | fifty percent (50%) of the outstanding shares or beneficial
86 | ownership of such entity.
87 |
88 | 2. License Grants and Conditions
89 | --------------------------------
90 |
91 | 2.1. Grants
92 |
93 | Each Contributor hereby grants You a world-wide, royalty-free,
94 | non-exclusive license:
95 |
96 | (a) under intellectual property rights (other than patent or trademark)
97 | Licensable by such Contributor to use, reproduce, make available,
98 | modify, display, perform, distribute, and otherwise exploit its
99 | Contributions, either on an unmodified basis, with Modifications, or
100 | as part of a Larger Work; and
101 |
102 | (b) under Patent Claims of such Contributor to make, use, sell, offer
103 | for sale, have made, import, and otherwise transfer either its
104 | Contributions or its Contributor Version.
105 |
106 | 2.2. Effective Date
107 |
108 | The licenses granted in Section 2.1 with respect to any Contribution
109 | become effective for each Contribution on the date the Contributor first
110 | distributes such Contribution.
111 |
112 | 2.3. Limitations on Grant Scope
113 |
114 | The licenses granted in this Section 2 are the only rights granted under
115 | this License. No additional rights or licenses will be implied from the
116 | distribution or licensing of Covered Software under this License.
117 | Notwithstanding Section 2.1(b) above, no patent license is granted by a
118 | Contributor:
119 |
120 | (a) for any code that a Contributor has removed from Covered Software;
121 | or
122 |
123 | (b) for infringements caused by: (i) Your and any other third party's
124 | modifications of Covered Software, or (ii) the combination of its
125 | Contributions with other software (except as part of its Contributor
126 | Version); or
127 |
128 | (c) under Patent Claims infringed by Covered Software in the absence of
129 | its Contributions.
130 |
131 | This License does not grant any rights in the trademarks, service marks,
132 | or logos of any Contributor (except as may be necessary to comply with
133 | the notice requirements in Section 3.4).
134 |
135 | 2.4. Subsequent Licenses
136 |
137 | No Contributor makes additional grants as a result of Your choice to
138 | distribute the Covered Software under a subsequent version of this
139 | License (see Section 10.2) or under the terms of a Secondary License (if
140 | permitted under the terms of Section 3.3).
141 |
142 | 2.5. Representation
143 |
144 | Each Contributor represents that the Contributor believes its
145 | Contributions are its original creation(s) or it has sufficient rights
146 | to grant the rights to its Contributions conveyed by this License.
147 |
148 | 2.6. Fair Use
149 |
150 | This License is not intended to limit any rights You have under
151 | applicable copyright doctrines of fair use, fair dealing, or other
152 | equivalents.
153 |
154 | 2.7. Conditions
155 |
156 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
157 | in Section 2.1.
158 |
159 | 3. Responsibilities
160 | -------------------
161 |
162 | 3.1. Distribution of Source Form
163 |
164 | All distribution of Covered Software in Source Code Form, including any
165 | Modifications that You create or to which You contribute, must be under
166 | the terms of this License. You must inform recipients that the Source
167 | Code Form of the Covered Software is governed by the terms of this
168 | License, and how they can obtain a copy of this License. You may not
169 | attempt to alter or restrict the recipients' rights in the Source Code
170 | Form.
171 |
172 | 3.2. Distribution of Executable Form
173 |
174 | If You distribute Covered Software in Executable Form then:
175 |
176 | (a) such Covered Software must also be made available in Source Code
177 | Form, as described in Section 3.1, and You must inform recipients of
178 | the Executable Form how they can obtain a copy of such Source Code
179 | Form by reasonable means in a timely manner, at a charge no more
180 | than the cost of distribution to the recipient; and
181 |
182 | (b) You may distribute such Executable Form under the terms of this
183 | License, or sublicense it under different terms, provided that the
184 | license for the Executable Form does not attempt to limit or alter
185 | the recipients' rights in the Source Code Form under this License.
186 |
187 | 3.3. Distribution of a Larger Work
188 |
189 | You may create and distribute a Larger Work under terms of Your choice,
190 | provided that You also comply with the requirements of this License for
191 | the Covered Software. If the Larger Work is a combination of Covered
192 | Software with a work governed by one or more Secondary Licenses, and the
193 | Covered Software is not Incompatible With Secondary Licenses, this
194 | License permits You to additionally distribute such Covered Software
195 | under the terms of such Secondary License(s), so that the recipient of
196 | the Larger Work may, at their option, further distribute the Covered
197 | Software under the terms of either this License or such Secondary
198 | License(s).
199 |
200 | 3.4. Notices
201 |
202 | You may not remove or alter the substance of any license notices
203 | (including copyright notices, patent notices, disclaimers of warranty,
204 | or limitations of liability) contained within the Source Code Form of
205 | the Covered Software, except that You may alter any license notices to
206 | the extent required to remedy known factual inaccuracies.
207 |
208 | 3.5. Application of Additional Terms
209 |
210 | You may choose to offer, and to charge a fee for, warranty, support,
211 | indemnity or liability obligations to one or more recipients of Covered
212 | Software. However, You may do so only on Your own behalf, and not on
213 | behalf of any Contributor. You must make it absolutely clear that any
214 | such warranty, support, indemnity, or liability obligation is offered by
215 | You alone, and You hereby agree to indemnify every Contributor for any
216 | liability incurred by such Contributor as a result of warranty, support,
217 | indemnity or liability terms You offer. You may include additional
218 | disclaimers of warranty and limitations of liability specific to any
219 | jurisdiction.
220 |
221 | 4. Inability to Comply Due to Statute or Regulation
222 | ---------------------------------------------------
223 |
224 | If it is impossible for You to comply with any of the terms of this
225 | License with respect to some or all of the Covered Software due to
226 | statute, judicial order, or regulation then You must: (a) comply with
227 | the terms of this License to the maximum extent possible; and (b)
228 | describe the limitations and the code they affect. Such description must
229 | be placed in a text file included with all distributions of the Covered
230 | Software under this License. Except to the extent prohibited by statute
231 | or regulation, such description must be sufficiently detailed for a
232 | recipient of ordinary skill to be able to understand it.
233 |
234 | 5. Termination
235 | --------------
236 |
237 | 5.1. The rights granted under this License will terminate automatically
238 | if You fail to comply with any of its terms. However, if You become
239 | compliant, then the rights granted under this License from a particular
240 | Contributor are reinstated (a) provisionally, unless and until such
241 | Contributor explicitly and finally terminates Your grants, and (b) on an
242 | ongoing basis, if such Contributor fails to notify You of the
243 | non-compliance by some reasonable means prior to 60 days after You have
244 | come back into compliance. Moreover, Your grants from a particular
245 | Contributor are reinstated on an ongoing basis if such Contributor
246 | notifies You of the non-compliance by some reasonable means, this is the
247 | first time You have received notice of non-compliance with this License
248 | from such Contributor, and You become compliant prior to 30 days after
249 | Your receipt of the notice.
250 |
251 | 5.2. If You initiate litigation against any entity by asserting a patent
252 | infringement claim (excluding declaratory judgment actions,
253 | counter-claims, and cross-claims) alleging that a Contributor Version
254 | directly or indirectly infringes any patent, then the rights granted to
255 | You by any and all Contributors for the Covered Software under Section
256 | 2.1 of this License shall terminate.
257 |
258 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all
259 | end user license agreements (excluding distributors and resellers) which
260 | have been validly granted by You or Your distributors under this License
261 | prior to termination shall survive termination.
262 |
263 | ************************************************************************
264 | * *
265 | * 6. Disclaimer of Warranty *
266 | * ------------------------- *
267 | * *
268 | * Covered Software is provided under this License on an "as is" *
269 | * basis, without warranty of any kind, either expressed, implied, or *
270 | * statutory, including, without limitation, warranties that the *
271 | * Covered Software is free of defects, merchantable, fit for a *
272 | * particular purpose or non-infringing. The entire risk as to the *
273 | * quality and performance of the Covered Software is with You. *
274 | * Should any Covered Software prove defective in any respect, You *
275 | * (not any Contributor) assume the cost of any necessary servicing, *
276 | * repair, or correction. This disclaimer of warranty constitutes an *
277 | * essential part of this License. No use of any Covered Software is *
278 | * authorized under this License except under this disclaimer. *
279 | * *
280 | ************************************************************************
281 |
282 | ************************************************************************
283 | * *
284 | * 7. Limitation of Liability *
285 | * -------------------------- *
286 | * *
287 | * Under no circumstances and under no legal theory, whether tort *
288 | * (including negligence), contract, or otherwise, shall any *
289 | * Contributor, or anyone who distributes Covered Software as *
290 | * permitted above, be liable to You for any direct, indirect, *
291 | * special, incidental, or consequential damages of any character *
292 | * including, without limitation, damages for lost profits, loss of *
293 | * goodwill, work stoppage, computer failure or malfunction, or any *
294 | * and all other commercial damages or losses, even if such party *
295 | * shall have been informed of the possibility of such damages. This *
296 | * limitation of liability shall not apply to liability for death or *
297 | * personal injury resulting from such party's negligence to the *
298 | * extent applicable law prohibits such limitation. Some *
299 | * jurisdictions do not allow the exclusion or limitation of *
300 | * incidental or consequential damages, so this exclusion and *
301 | * limitation may not apply to You. *
302 | * *
303 | ************************************************************************
304 |
305 | 8. Litigation
306 | -------------
307 |
308 | Any litigation relating to this License may be brought only in the
309 | courts of a jurisdiction where the defendant maintains its principal
310 | place of business and such litigation shall be governed by laws of that
311 | jurisdiction, without reference to its conflict-of-law provisions.
312 | Nothing in this Section shall prevent a party's ability to bring
313 | cross-claims or counter-claims.
314 |
315 | 9. Miscellaneous
316 | ----------------
317 |
318 | This License represents the complete agreement concerning the subject
319 | matter hereof. If any provision of this License is held to be
320 | unenforceable, such provision shall be reformed only to the extent
321 | necessary to make it enforceable. Any law or regulation which provides
322 | that the language of a contract shall be construed against the drafter
323 | shall not be used to construe this License against a Contributor.
324 |
325 | 10. Versions of the License
326 | ---------------------------
327 |
328 | 10.1. New Versions
329 |
330 | Mozilla Foundation is the license steward. Except as provided in Section
331 | 10.3, no one other than the license steward has the right to modify or
332 | publish new versions of this License. Each version will be given a
333 | distinguishing version number.
334 |
335 | 10.2. Effect of New Versions
336 |
337 | You may distribute the Covered Software under the terms of the version
338 | of the License under which You originally received the Covered Software,
339 | or under the terms of any subsequent version published by the license
340 | steward.
341 |
342 | 10.3. Modified Versions
343 |
344 | If you create software not governed by this License, and you want to
345 | create a new license for such software, you may create and use a
346 | modified version of this License if you rename the license and remove
347 | any references to the name of the license steward (except to note that
348 | such modified license differs from this License).
349 |
350 | 10.4. Distributing Source Code Form that is Incompatible With Secondary
351 | Licenses
352 |
353 | If You choose to distribute Source Code Form that is Incompatible With
354 | Secondary Licenses under the terms of this version of the License, the
355 | notice described in Exhibit B of this License must be attached.
356 |
357 | Exhibit A - Source Code Form License Notice
358 | -------------------------------------------
359 |
360 | This Source Code Form is subject to the terms of the Mozilla Public
361 | License, v. 2.0. If a copy of the MPL was not distributed with this
362 | file, You can obtain one at http://mozilla.org/MPL/2.0/.
363 |
364 | If it is not possible or desirable to put the notice in a particular
365 | file, then You may include the notice in a location (such as a LICENSE
366 | file in a relevant directory) where a recipient would be likely to look
367 | for such a notice.
368 |
369 | You may add additional accurate notices of copyright ownership.
370 |
371 | Exhibit B - "Incompatible With Secondary Licenses" Notice
372 | ---------------------------------------------------------
373 |
374 | This Source Code Form is "Incompatible With Secondary Licenses", as
375 | defined by the Mozilla Public License, v. 2.0.
376 |
--------------------------------------------------------------------------------
/docs/data-sources/panel_alert_groups.md:
--------------------------------------------------------------------------------
1 | ---
2 | # generated by https://github.com/hashicorp/terraform-plugin-docs
3 | page_title: "schemas_panel_alert_groups Data Source - terraform-provider-schemas"
4 | subcategory: ""
5 | description: |-
6 |
7 | ---
8 |
9 | # schemas_panel_alert_groups (Data Source)
10 |
11 |
12 |
13 |
14 |
15 |
16 | ## Schema
17 |
18 | ### Optional
19 |
20 | - `datasource` (Attributes) The datasource used in all targets. (see [below for nested schema](#nestedatt--datasource))
21 | - `description` (String) Panel description.
22 | - `field_config` (Attributes) Field options allow you to change how the data is displayed in your visualizations. (see [below for nested schema](#nestedatt--field_config))
23 | - `grid_pos` (Attributes) Grid position. (see [below for nested schema](#nestedatt--grid_pos))
24 | - `interval` (String) The min time interval setting defines a lower limit for the $__interval and $__interval_ms variables.
25 | This value must be formatted as a number followed by a valid time
26 | identifier like: "40s", "3d", etc.
27 | See: https://grafana.com/docs/grafana/latest/panels-visualizations/query-transform-data/#query-options
28 | - `library_panel` (Attributes) Dynamically load the panel (see [below for nested schema](#nestedatt--library_panel))
29 | - `links` (Attributes List) Panel links. (see [below for nested schema](#nestedatt--links))
30 | - `max_data_points` (Number) The maximum number of data points that the panel queries are retrieving.
31 | - `options` (Attributes) (see [below for nested schema](#nestedatt--options))
32 | - `plugin_version` (String) The version of the plugin that is used for this panel. This is used to find the plugin to display the panel and to migrate old panel configs.
33 | - `repeat` (String) Name of template variable to repeat for.
34 | - `repeat_direction` (String) Direction to repeat in if 'repeat' is set.
35 | h for horizontal, v for vertical. Defaults to "h".
36 | - `repeat_panel_id` (Number) Id of the repeating panel.
37 | - `tags` (List of String) Tags for the panel.
38 | - `targets` (List of String) Depends on the panel plugin. See the plugin documentation for details.
39 | - `time_from` (String) Overrides the relative time range for individual panels,
40 | which causes them to be different than what is selected in
41 | the dashboard time picker in the top-right corner of the dashboard. You can use this to show metrics from different
42 | time periods or days on the same dashboard.
43 | The value is formatted as time operation like: now-5m (Last 5 minutes), now/d (the day so far),
44 | now-5d/d(Last 5 days), now/w (This week so far), now-2y/y (Last 2 years).
45 | Note: Panel time overrides have no effect when the dashboard’s time range is absolute.
46 | See: https://grafana.com/docs/grafana/latest/panels-visualizations/query-transform-data/#query-options
47 | - `time_shift` (String) Overrides the time range for individual panels by shifting its start and end relative to the time picker.
48 | For example, you can shift the time range for the panel to be two hours earlier than the dashboard time picker setting 2h.
49 | Note: Panel time overrides have no effect when the dashboard’s time range is absolute.
50 | See: https://grafana.com/docs/grafana/latest/panels-visualizations/query-transform-data/#query-options
51 | - `title` (String) Panel title.
52 | - `transformations` (Attributes List) List of transformations that are applied to the panel data before rendering.
53 | When there are multiple transformations, Grafana applies them in the order they are listed.
54 | Each transformation creates a result set that then passes on to the next transformation in the processing pipeline. (see [below for nested schema](#nestedatt--transformations))
55 | - `transparent` (Boolean) Whether to display the panel without a background. Defaults to false.
56 | - `type` (String) The panel plugin type id. This is used to find the plugin to display the panel. Defaults to "alertGroups".
57 |
58 | ### Read-Only
59 |
60 | - `rendered_json` (String) This datasource rendered as JSON
61 |
62 |
63 | ### Nested Schema for `datasource`
64 |
65 | Optional:
66 |
67 | - `type` (String) The plugin type-id
68 | - `uid` (String) Specific datasource instance
69 |
70 |
71 |
72 | ### Nested Schema for `field_config`
73 |
74 | Optional:
75 |
76 | - `defaults` (Attributes) Defaults are the options applied to all fields. (see [below for nested schema](#nestedatt--field_config--defaults))
77 | - `overrides` (Attributes List) Overrides are the options applied to specific fields overriding the defaults. (see [below for nested schema](#nestedatt--field_config--overrides))
78 |
79 |
80 | ### Nested Schema for `field_config.defaults`
81 |
82 | Optional:
83 |
84 | - `color` (Attributes) Panel color configuration (see [below for nested schema](#nestedatt--field_config--defaults--color))
85 | - `custom` (Attributes) custom is specified by the FieldConfig field
86 | in panel plugin schemas. (see [below for nested schema](#nestedatt--field_config--defaults--custom))
87 | - `decimals` (Number) Specify the number of decimals Grafana includes in the rendered value.
88 | If you leave this field blank, Grafana automatically truncates the number of decimals based on the value.
89 | For example 1.1234 will display as 1.12 and 100.456 will display as 100.
90 | To display all decimals, set the unit to String.
91 | - `description` (String) Human readable field metadata
92 | - `display_name` (String) The display value for this field. This supports template variables blank is auto
93 | - `display_name_from_ds` (String) This can be used by data sources that return and explicit naming structure for values and labels
94 | When this property is configured, this value is used rather than the default naming strategy.
95 | - `filterable` (Boolean) True if data source field supports ad-hoc filters
96 | - `mappings` (Attributes List) Convert input values into a display string (see [below for nested schema](#nestedatt--field_config--defaults--mappings))
97 | - `max` (Number) The maximum value used in percentage threshold calculations. Leave blank for auto calculation based on all series and fields.
98 | - `min` (Number) The minimum value used in percentage threshold calculations. Leave blank for auto calculation based on all series and fields.
99 | - `no_value` (String) Alternative to empty string
100 | - `path` (String) An explicit path to the field in the datasource. When the frame meta includes a path,
101 | This will default to ${frame.meta.path}/${field.name}
102 |
103 | When defined, this value can be used as an identifier within the datasource scope, and
104 | may be used to update the results
105 | - `thresholds` (Attributes) Map numeric values to states (see [below for nested schema](#nestedatt--field_config--defaults--thresholds))
106 | - `unit` (String) Unit a field should use. The unit you select is applied to all fields except time.
107 | You can use the units ID availables in Grafana or a custom unit.
108 | Available units in Grafana: https://github.com/grafana/grafana/blob/main/packages/grafana-data/src/valueFormats/categories.ts
109 | As custom unit, you can use the following formats:
110 | suffix: for custom unit that should go after value.
111 | prefix: for custom unit that should go before value.
112 | time: For custom date time formats type for example time:YYYY-MM-DD.
113 | si: for custom SI units. For example: si: mF. This one is a bit more advanced as you can specify both a unit and the source data scale. So if your source data is represented as milli (thousands of) something prefix the unit with that SI scale character.
114 | count: for a custom count unit.
115 | currency: for custom a currency unit.
116 | - `writeable` (Boolean) True if data source can write a value to the path. Auth/authz are supported separately
117 |
118 |
119 | ### Nested Schema for `field_config.defaults.color`
120 |
121 | Required:
122 |
123 | - `mode` (String) The main color scheme mode.
124 |
125 | Optional:
126 |
127 | - `fixed_color` (String) The fixed color value for fixed or shades color modes.
128 | - `series_by` (String) Some visualizations need to know how to assign a series color from by value color schemes.
129 |
130 |
131 |
132 | ### Nested Schema for `field_config.defaults.custom`
133 |
134 |
135 |
136 | ### Nested Schema for `field_config.defaults.mappings`
137 |
138 | Optional:
139 |
140 | - `range_map` (Attributes) (see [below for nested schema](#nestedatt--field_config--defaults--mappings--range_map))
141 | - `regex_map` (Attributes) (see [below for nested schema](#nestedatt--field_config--defaults--mappings--regex_map))
142 | - `special_value_map` (Attributes) (see [below for nested schema](#nestedatt--field_config--defaults--mappings--special_value_map))
143 | - `value_map` (Attributes) (see [below for nested schema](#nestedatt--field_config--defaults--mappings--value_map))
144 |
145 |
146 | ### Nested Schema for `field_config.defaults.mappings.value_map`
147 |
148 | Required:
149 |
150 | - `type` (String)
151 |
152 | Optional:
153 |
154 | - `options` (Attributes) Range to match against and the result to apply when the value is within the range (see [below for nested schema](#nestedatt--field_config--defaults--mappings--value_map--options))
155 |
156 |
157 | ### Nested Schema for `field_config.defaults.mappings.value_map.options`
158 |
159 | Required:
160 |
161 | - `from` (String) Min value of the range. It can be null which means -Infinity
162 | - `to` (String) Max value of the range. It can be null which means +Infinity
163 |
164 | Optional:
165 |
166 | - `result` (Attributes) Config to apply when the value is within the range (see [below for nested schema](#nestedatt--field_config--defaults--mappings--value_map--options--result))
167 |
168 |
169 | ### Nested Schema for `field_config.defaults.mappings.value_map.options.result`
170 |
171 | Optional:
172 |
173 | - `color` (String) Text to use when the value matches
174 | - `icon` (String) Icon to display when the value matches. Only specific visualizations.
175 | - `index` (Number) Position in the mapping array. Only used internally.
176 | - `text` (String) Text to display when the value matches
177 |
178 |
179 |
180 |
181 |
182 | ### Nested Schema for `field_config.defaults.mappings.value_map`
183 |
184 | Required:
185 |
186 | - `type` (String)
187 |
188 | Optional:
189 |
190 | - `options` (Attributes) Regular expression to match against and the result to apply when the value matches the regex (see [below for nested schema](#nestedatt--field_config--defaults--mappings--value_map--options))
191 |
192 |
193 | ### Nested Schema for `field_config.defaults.mappings.value_map.options`
194 |
195 | Required:
196 |
197 | - `pattern` (String) Regular expression to match against
198 |
199 | Optional:
200 |
201 | - `result` (Attributes) Config to apply when the value matches the regex (see [below for nested schema](#nestedatt--field_config--defaults--mappings--value_map--options--result))
202 |
203 |
204 | ### Nested Schema for `field_config.defaults.mappings.value_map.options.result`
205 |
206 | Optional:
207 |
208 | - `color` (String) Text to use when the value matches
209 | - `icon` (String) Icon to display when the value matches. Only specific visualizations.
210 | - `index` (Number) Position in the mapping array. Only used internally.
211 | - `text` (String) Text to display when the value matches
212 |
213 |
214 |
215 |
216 |
217 | ### Nested Schema for `field_config.defaults.mappings.value_map`
218 |
219 | Required:
220 |
221 | - `type` (String)
222 |
223 | Optional:
224 |
225 | - `options` (Attributes) (see [below for nested schema](#nestedatt--field_config--defaults--mappings--value_map--options))
226 |
227 |
228 | ### Nested Schema for `field_config.defaults.mappings.value_map.options`
229 |
230 | Required:
231 |
232 | - `match` (String) Special value to match against
233 |
234 | Optional:
235 |
236 | - `result` (Attributes) Config to apply when the value matches the special value (see [below for nested schema](#nestedatt--field_config--defaults--mappings--value_map--options--result))
237 |
238 |
239 | ### Nested Schema for `field_config.defaults.mappings.value_map.options.result`
240 |
241 | Optional:
242 |
243 | - `color` (String) Text to use when the value matches
244 | - `icon` (String) Icon to display when the value matches. Only specific visualizations.
245 | - `index` (Number) Position in the mapping array. Only used internally.
246 | - `text` (String) Text to display when the value matches
247 |
248 |
249 |
250 |
251 |
252 | ### Nested Schema for `field_config.defaults.mappings.value_map`
253 |
254 | Required:
255 |
256 | - `type` (String)
257 |
258 | Optional:
259 |
260 | - `options` (Attributes Map) Map with : ValueMappingResult. For example: { "10": { text: "Perfection!", color: "green" } } (see [below for nested schema](#nestedatt--field_config--defaults--mappings--value_map--options))
261 |
262 |
263 | ### Nested Schema for `field_config.defaults.mappings.value_map.options`
264 |
265 | Optional:
266 |
267 | - `color` (String) Text to use when the value matches
268 | - `icon` (String) Icon to display when the value matches. Only specific visualizations.
269 | - `index` (Number) Position in the mapping array. Only used internally.
270 | - `text` (String) Text to display when the value matches
271 |
272 |
273 |
274 |
275 |
276 | ### Nested Schema for `field_config.defaults.thresholds`
277 |
278 | Required:
279 |
280 | - `mode` (String) Thresholds mode.
281 |
282 | Optional:
283 |
284 | - `steps` (Attributes List) Must be sorted by 'value', first value is always -Infinity (see [below for nested schema](#nestedatt--field_config--defaults--thresholds--steps))
285 |
286 |
287 | ### Nested Schema for `field_config.defaults.thresholds.steps`
288 |
289 | Required:
290 |
291 | - `color` (String) Color represents the color of the visual change that will occur in the dashboard when the threshold value is met or exceeded.
292 | - `value` (String) Value represents a specified metric for the threshold, which triggers a visual change in the dashboard when this value is met or exceeded.
293 | Nulls currently appear here when serializing -Infinity to JSON.
294 |
295 |
296 |
297 |
298 |
299 | ### Nested Schema for `field_config.overrides`
300 |
301 | Optional:
302 |
303 | - `matcher` (Attributes) (see [below for nested schema](#nestedatt--field_config--overrides--matcher))
304 | - `properties` (Attributes List) (see [below for nested schema](#nestedatt--field_config--overrides--properties))
305 |
306 |
307 | ### Nested Schema for `field_config.overrides.matcher`
308 |
309 |
310 |
311 | ### Nested Schema for `field_config.overrides.properties`
312 |
313 |
314 |
315 |
316 |
317 | ### Nested Schema for `grid_pos`
318 |
319 | Optional:
320 |
321 | - `h` (Number) Panel height. The height is the number of rows from the top edge of the panel. Defaults to 9.
322 | - `static` (Boolean) Whether the panel is fixed within the grid. If true, the panel will not be affected by other panels' interactions
323 | - `w` (Number) Panel width. The width is the number of columns from the left edge of the panel. Defaults to 12.
324 | - `x` (Number) Panel x. The x coordinate is the number of columns from the left edge of the grid. Defaults to 0.
325 | - `y` (Number) Panel y. The y coordinate is the number of rows from the top edge of the grid. Defaults to 0.
326 |
327 |
328 |
329 | ### Nested Schema for `library_panel`
330 |
331 | Required:
332 |
333 | - `name` (String) Library panel name
334 | - `uid` (String) Library panel uid
335 |
336 |
337 |
338 | ### Nested Schema for `links`
339 |
340 | Required:
341 |
342 | - `icon` (String) Icon name to be displayed with the link
343 | - `title` (String) Title to display with the link
344 | - `tooltip` (String) Tooltip to display when the user hovers their mouse over it
345 | - `type` (String) Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource)
346 | - `url` (String) Link URL. Only required/valid if the type is link
347 |
348 | Optional:
349 |
350 | - `as_dropdown` (Boolean) If true, all dashboards links will be displayed in a dropdown. If false, all dashboards links will be displayed side by side. Only valid if the type is dashboards. Defaults to false.
351 | - `include_vars` (Boolean) If true, includes current template variables values in the link as query params. Defaults to false.
352 | - `keep_time` (Boolean) If true, includes current time range in the link as query params. Defaults to false.
353 | - `tags` (List of String) List of tags to limit the linked dashboards. If empty, all dashboards will be displayed. Only valid if the type is dashboards
354 | - `target_blank` (Boolean) If true, the link will be opened in a new tab. Defaults to false.
355 |
356 |
357 |
358 | ### Nested Schema for `options`
359 |
360 | Required:
361 |
362 | - `alertmanager` (String) Name of the alertmanager used as a source for alerts
363 | - `expand_all` (Boolean) Expand all alert groups by default
364 | - `labels` (String) Comma-separated list of values used to filter alert results
365 |
366 |
367 |
368 | ### Nested Schema for `transformations`
369 |
370 | Optional:
371 |
372 | - `disabled` (Boolean) Disabled transformations are skipped
373 | - `filter` (Attributes) Optional frame matcher. When missing it will be applied to all results (see [below for nested schema](#nestedatt--transformations--filter))
374 |
375 |
376 | ### Nested Schema for `transformations.filter`
377 |
--------------------------------------------------------------------------------
/docs/data-sources/panel_annotations_list.md:
--------------------------------------------------------------------------------
1 | ---
2 | # generated by https://github.com/hashicorp/terraform-plugin-docs
3 | page_title: "schemas_panel_annotations_list Data Source - terraform-provider-schemas"
4 | subcategory: ""
5 | description: |-
6 |
7 | ---
8 |
9 | # schemas_panel_annotations_list (Data Source)
10 |
11 |
12 |
13 |
14 |
15 |
16 | ## Schema
17 |
18 | ### Optional
19 |
20 | - `datasource` (Attributes) The datasource used in all targets. (see [below for nested schema](#nestedatt--datasource))
21 | - `description` (String) Panel description.
22 | - `field_config` (Attributes) Field options allow you to change how the data is displayed in your visualizations. (see [below for nested schema](#nestedatt--field_config))
23 | - `grid_pos` (Attributes) Grid position. (see [below for nested schema](#nestedatt--grid_pos))
24 | - `interval` (String) The min time interval setting defines a lower limit for the $__interval and $__interval_ms variables.
25 | This value must be formatted as a number followed by a valid time
26 | identifier like: "40s", "3d", etc.
27 | See: https://grafana.com/docs/grafana/latest/panels-visualizations/query-transform-data/#query-options
28 | - `library_panel` (Attributes) Dynamically load the panel (see [below for nested schema](#nestedatt--library_panel))
29 | - `links` (Attributes List) Panel links. (see [below for nested schema](#nestedatt--links))
30 | - `max_data_points` (Number) The maximum number of data points that the panel queries are retrieving.
31 | - `options` (Attributes) (see [below for nested schema](#nestedatt--options))
32 | - `plugin_version` (String) The version of the plugin that is used for this panel. This is used to find the plugin to display the panel and to migrate old panel configs.
33 | - `repeat` (String) Name of template variable to repeat for.
34 | - `repeat_direction` (String) Direction to repeat in if 'repeat' is set.
35 | h for horizontal, v for vertical. Defaults to "h".
36 | - `repeat_panel_id` (Number) Id of the repeating panel.
37 | - `tags` (List of String) Tags for the panel.
38 | - `targets` (List of String) Depends on the panel plugin. See the plugin documentation for details.
39 | - `time_from` (String) Overrides the relative time range for individual panels,
40 | which causes them to be different than what is selected in
41 | the dashboard time picker in the top-right corner of the dashboard. You can use this to show metrics from different
42 | time periods or days on the same dashboard.
43 | The value is formatted as time operation like: now-5m (Last 5 minutes), now/d (the day so far),
44 | now-5d/d(Last 5 days), now/w (This week so far), now-2y/y (Last 2 years).
45 | Note: Panel time overrides have no effect when the dashboard’s time range is absolute.
46 | See: https://grafana.com/docs/grafana/latest/panels-visualizations/query-transform-data/#query-options
47 | - `time_shift` (String) Overrides the time range for individual panels by shifting its start and end relative to the time picker.
48 | For example, you can shift the time range for the panel to be two hours earlier than the dashboard time picker setting 2h.
49 | Note: Panel time overrides have no effect when the dashboard’s time range is absolute.
50 | See: https://grafana.com/docs/grafana/latest/panels-visualizations/query-transform-data/#query-options
51 | - `title` (String) Panel title.
52 | - `transformations` (Attributes List) List of transformations that are applied to the panel data before rendering.
53 | When there are multiple transformations, Grafana applies them in the order they are listed.
54 | Each transformation creates a result set that then passes on to the next transformation in the processing pipeline. (see [below for nested schema](#nestedatt--transformations))
55 | - `transparent` (Boolean) Whether to display the panel without a background. Defaults to false.
56 | - `type` (String) The panel plugin type id. This is used to find the plugin to display the panel. Defaults to "annolist".
57 |
58 | ### Read-Only
59 |
60 | - `rendered_json` (String) This datasource rendered as JSON
61 |
62 |
63 | ### Nested Schema for `datasource`
64 |
65 | Optional:
66 |
67 | - `type` (String) The plugin type-id
68 | - `uid` (String) Specific datasource instance
69 |
70 |
71 |
72 | ### Nested Schema for `field_config`
73 |
74 | Optional:
75 |
76 | - `defaults` (Attributes) Defaults are the options applied to all fields. (see [below for nested schema](#nestedatt--field_config--defaults))
77 | - `overrides` (Attributes List) Overrides are the options applied to specific fields overriding the defaults. (see [below for nested schema](#nestedatt--field_config--overrides))
78 |
79 |
80 | ### Nested Schema for `field_config.defaults`
81 |
82 | Optional:
83 |
84 | - `color` (Attributes) Panel color configuration (see [below for nested schema](#nestedatt--field_config--defaults--color))
85 | - `custom` (Attributes) custom is specified by the FieldConfig field
86 | in panel plugin schemas. (see [below for nested schema](#nestedatt--field_config--defaults--custom))
87 | - `decimals` (Number) Specify the number of decimals Grafana includes in the rendered value.
88 | If you leave this field blank, Grafana automatically truncates the number of decimals based on the value.
89 | For example 1.1234 will display as 1.12 and 100.456 will display as 100.
90 | To display all decimals, set the unit to String.
91 | - `description` (String) Human readable field metadata
92 | - `display_name` (String) The display value for this field. This supports template variables blank is auto
93 | - `display_name_from_ds` (String) This can be used by data sources that return and explicit naming structure for values and labels
94 | When this property is configured, this value is used rather than the default naming strategy.
95 | - `filterable` (Boolean) True if data source field supports ad-hoc filters
96 | - `mappings` (Attributes List) Convert input values into a display string (see [below for nested schema](#nestedatt--field_config--defaults--mappings))
97 | - `max` (Number) The maximum value used in percentage threshold calculations. Leave blank for auto calculation based on all series and fields.
98 | - `min` (Number) The minimum value used in percentage threshold calculations. Leave blank for auto calculation based on all series and fields.
99 | - `no_value` (String) Alternative to empty string
100 | - `path` (String) An explicit path to the field in the datasource. When the frame meta includes a path,
101 | This will default to ${frame.meta.path}/${field.name}
102 |
103 | When defined, this value can be used as an identifier within the datasource scope, and
104 | may be used to update the results
105 | - `thresholds` (Attributes) Map numeric values to states (see [below for nested schema](#nestedatt--field_config--defaults--thresholds))
106 | - `unit` (String) Unit a field should use. The unit you select is applied to all fields except time.
107 | You can use the units ID availables in Grafana or a custom unit.
108 | Available units in Grafana: https://github.com/grafana/grafana/blob/main/packages/grafana-data/src/valueFormats/categories.ts
109 | As custom unit, you can use the following formats:
110 | suffix: for custom unit that should go after value.
111 | prefix: for custom unit that should go before value.
112 | time: For custom date time formats type for example time:YYYY-MM-DD.
113 | si: for custom SI units. For example: si: mF. This one is a bit more advanced as you can specify both a unit and the source data scale. So if your source data is represented as milli (thousands of) something prefix the unit with that SI scale character.
114 | count: for a custom count unit.
115 | currency: for custom a currency unit.
116 | - `writeable` (Boolean) True if data source can write a value to the path. Auth/authz are supported separately
117 |
118 |
119 | ### Nested Schema for `field_config.defaults.color`
120 |
121 | Required:
122 |
123 | - `mode` (String) The main color scheme mode.
124 |
125 | Optional:
126 |
127 | - `fixed_color` (String) The fixed color value for fixed or shades color modes.
128 | - `series_by` (String) Some visualizations need to know how to assign a series color from by value color schemes.
129 |
130 |
131 |
132 | ### Nested Schema for `field_config.defaults.custom`
133 |
134 |
135 |
136 | ### Nested Schema for `field_config.defaults.mappings`
137 |
138 | Optional:
139 |
140 | - `range_map` (Attributes) (see [below for nested schema](#nestedatt--field_config--defaults--mappings--range_map))
141 | - `regex_map` (Attributes) (see [below for nested schema](#nestedatt--field_config--defaults--mappings--regex_map))
142 | - `special_value_map` (Attributes) (see [below for nested schema](#nestedatt--field_config--defaults--mappings--special_value_map))
143 | - `value_map` (Attributes) (see [below for nested schema](#nestedatt--field_config--defaults--mappings--value_map))
144 |
145 |
146 | ### Nested Schema for `field_config.defaults.mappings.value_map`
147 |
148 | Required:
149 |
150 | - `type` (String)
151 |
152 | Optional:
153 |
154 | - `options` (Attributes) Range to match against and the result to apply when the value is within the range (see [below for nested schema](#nestedatt--field_config--defaults--mappings--value_map--options))
155 |
156 |
157 | ### Nested Schema for `field_config.defaults.mappings.value_map.options`
158 |
159 | Required:
160 |
161 | - `from` (String) Min value of the range. It can be null which means -Infinity
162 | - `to` (String) Max value of the range. It can be null which means +Infinity
163 |
164 | Optional:
165 |
166 | - `result` (Attributes) Config to apply when the value is within the range (see [below for nested schema](#nestedatt--field_config--defaults--mappings--value_map--options--result))
167 |
168 |
169 | ### Nested Schema for `field_config.defaults.mappings.value_map.options.result`
170 |
171 | Optional:
172 |
173 | - `color` (String) Text to use when the value matches
174 | - `icon` (String) Icon to display when the value matches. Only specific visualizations.
175 | - `index` (Number) Position in the mapping array. Only used internally.
176 | - `text` (String) Text to display when the value matches
177 |
178 |
179 |
180 |
181 |
182 | ### Nested Schema for `field_config.defaults.mappings.value_map`
183 |
184 | Required:
185 |
186 | - `type` (String)
187 |
188 | Optional:
189 |
190 | - `options` (Attributes) Regular expression to match against and the result to apply when the value matches the regex (see [below for nested schema](#nestedatt--field_config--defaults--mappings--value_map--options))
191 |
192 |
193 | ### Nested Schema for `field_config.defaults.mappings.value_map.options`
194 |
195 | Required:
196 |
197 | - `pattern` (String) Regular expression to match against
198 |
199 | Optional:
200 |
201 | - `result` (Attributes) Config to apply when the value matches the regex (see [below for nested schema](#nestedatt--field_config--defaults--mappings--value_map--options--result))
202 |
203 |
204 | ### Nested Schema for `field_config.defaults.mappings.value_map.options.result`
205 |
206 | Optional:
207 |
208 | - `color` (String) Text to use when the value matches
209 | - `icon` (String) Icon to display when the value matches. Only specific visualizations.
210 | - `index` (Number) Position in the mapping array. Only used internally.
211 | - `text` (String) Text to display when the value matches
212 |
213 |
214 |
215 |
216 |
217 | ### Nested Schema for `field_config.defaults.mappings.value_map`
218 |
219 | Required:
220 |
221 | - `type` (String)
222 |
223 | Optional:
224 |
225 | - `options` (Attributes) (see [below for nested schema](#nestedatt--field_config--defaults--mappings--value_map--options))
226 |
227 |
228 | ### Nested Schema for `field_config.defaults.mappings.value_map.options`
229 |
230 | Required:
231 |
232 | - `match` (String) Special value to match against
233 |
234 | Optional:
235 |
236 | - `result` (Attributes) Config to apply when the value matches the special value (see [below for nested schema](#nestedatt--field_config--defaults--mappings--value_map--options--result))
237 |
238 |
239 | ### Nested Schema for `field_config.defaults.mappings.value_map.options.result`
240 |
241 | Optional:
242 |
243 | - `color` (String) Text to use when the value matches
244 | - `icon` (String) Icon to display when the value matches. Only specific visualizations.
245 | - `index` (Number) Position in the mapping array. Only used internally.
246 | - `text` (String) Text to display when the value matches
247 |
248 |
249 |
250 |
251 |
252 | ### Nested Schema for `field_config.defaults.mappings.value_map`
253 |
254 | Required:
255 |
256 | - `type` (String)
257 |
258 | Optional:
259 |
260 | - `options` (Attributes Map) Map with : ValueMappingResult. For example: { "10": { text: "Perfection!", color: "green" } } (see [below for nested schema](#nestedatt--field_config--defaults--mappings--value_map--options))
261 |
262 |
263 | ### Nested Schema for `field_config.defaults.mappings.value_map.options`
264 |
265 | Optional:
266 |
267 | - `color` (String) Text to use when the value matches
268 | - `icon` (String) Icon to display when the value matches. Only specific visualizations.
269 | - `index` (Number) Position in the mapping array. Only used internally.
270 | - `text` (String) Text to display when the value matches
271 |
272 |
273 |
274 |
275 |
276 | ### Nested Schema for `field_config.defaults.thresholds`
277 |
278 | Required:
279 |
280 | - `mode` (String) Thresholds mode.
281 |
282 | Optional:
283 |
284 | - `steps` (Attributes List) Must be sorted by 'value', first value is always -Infinity (see [below for nested schema](#nestedatt--field_config--defaults--thresholds--steps))
285 |
286 |
287 | ### Nested Schema for `field_config.defaults.thresholds.steps`
288 |
289 | Required:
290 |
291 | - `color` (String) Color represents the color of the visual change that will occur in the dashboard when the threshold value is met or exceeded.
292 | - `value` (String) Value represents a specified metric for the threshold, which triggers a visual change in the dashboard when this value is met or exceeded.
293 | Nulls currently appear here when serializing -Infinity to JSON.
294 |
295 |
296 |
297 |
298 |
299 | ### Nested Schema for `field_config.overrides`
300 |
301 | Optional:
302 |
303 | - `matcher` (Attributes) (see [below for nested schema](#nestedatt--field_config--overrides--matcher))
304 | - `properties` (Attributes List) (see [below for nested schema](#nestedatt--field_config--overrides--properties))
305 |
306 |
307 | ### Nested Schema for `field_config.overrides.matcher`
308 |
309 |
310 |
311 | ### Nested Schema for `field_config.overrides.properties`
312 |
313 |
314 |
315 |
316 |
317 | ### Nested Schema for `grid_pos`
318 |
319 | Optional:
320 |
321 | - `h` (Number) Panel height. The height is the number of rows from the top edge of the panel. Defaults to 9.
322 | - `static` (Boolean) Whether the panel is fixed within the grid. If true, the panel will not be affected by other panels' interactions
323 | - `w` (Number) Panel width. The width is the number of columns from the left edge of the panel. Defaults to 12.
324 | - `x` (Number) Panel x. The x coordinate is the number of columns from the left edge of the grid. Defaults to 0.
325 | - `y` (Number) Panel y. The y coordinate is the number of rows from the top edge of the grid. Defaults to 0.
326 |
327 |
328 |
329 | ### Nested Schema for `library_panel`
330 |
331 | Required:
332 |
333 | - `name` (String) Library panel name
334 | - `uid` (String) Library panel uid
335 |
336 |
337 |
338 | ### Nested Schema for `links`
339 |
340 | Required:
341 |
342 | - `icon` (String) Icon name to be displayed with the link
343 | - `title` (String) Title to display with the link
344 | - `tooltip` (String) Tooltip to display when the user hovers their mouse over it
345 | - `type` (String) Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource)
346 | - `url` (String) Link URL. Only required/valid if the type is link
347 |
348 | Optional:
349 |
350 | - `as_dropdown` (Boolean) If true, all dashboards links will be displayed in a dropdown. If false, all dashboards links will be displayed side by side. Only valid if the type is dashboards. Defaults to false.
351 | - `include_vars` (Boolean) If true, includes current template variables values in the link as query params. Defaults to false.
352 | - `keep_time` (Boolean) If true, includes current time range in the link as query params. Defaults to false.
353 | - `tags` (List of String) List of tags to limit the linked dashboards. If empty, all dashboards will be displayed. Only valid if the type is dashboards
354 | - `target_blank` (Boolean) If true, the link will be opened in a new tab. Defaults to false.
355 |
356 |
357 |
358 | ### Nested Schema for `options`
359 |
360 | Optional:
361 |
362 | - `limit` (Number) Defaults to 10.
363 | - `navigate_after` (String) Defaults to "10m".
364 | - `navigate_before` (String) Defaults to "10m".
365 | - `navigate_to_panel` (Boolean) Defaults to true.
366 | - `only_from_this_dashboard` (Boolean) Defaults to false.
367 | - `only_in_time_range` (Boolean) Defaults to false.
368 | - `show_tags` (Boolean) Defaults to true.
369 | - `show_time` (Boolean) Defaults to true.
370 | - `show_user` (Boolean) Defaults to true.
371 | - `tags` (List of String)
372 |
373 |
374 |
375 | ### Nested Schema for `transformations`
376 |
377 | Optional:
378 |
379 | - `disabled` (Boolean) Disabled transformations are skipped
380 | - `filter` (Attributes) Optional frame matcher. When missing it will be applied to all results (see [below for nested schema](#nestedatt--transformations--filter))
381 |
382 |
383 | ### Nested Schema for `transformations.filter`
384 |
--------------------------------------------------------------------------------
/docs/data-sources/panel_text.md:
--------------------------------------------------------------------------------
1 | ---
2 | # generated by https://github.com/hashicorp/terraform-plugin-docs
3 | page_title: "schemas_panel_text Data Source - terraform-provider-schemas"
4 | subcategory: ""
5 | description: |-
6 |
7 | ---
8 |
9 | # schemas_panel_text (Data Source)
10 |
11 |
12 |
13 |
14 |
15 |
16 | ## Schema
17 |
18 | ### Optional
19 |
20 | - `datasource` (Attributes) The datasource used in all targets. (see [below for nested schema](#nestedatt--datasource))
21 | - `description` (String) Panel description.
22 | - `field_config` (Attributes) Field options allow you to change how the data is displayed in your visualizations. (see [below for nested schema](#nestedatt--field_config))
23 | - `grid_pos` (Attributes) Grid position. (see [below for nested schema](#nestedatt--grid_pos))
24 | - `interval` (String) The min time interval setting defines a lower limit for the $__interval and $__interval_ms variables.
25 | This value must be formatted as a number followed by a valid time
26 | identifier like: "40s", "3d", etc.
27 | See: https://grafana.com/docs/grafana/latest/panels-visualizations/query-transform-data/#query-options
28 | - `library_panel` (Attributes) Dynamically load the panel (see [below for nested schema](#nestedatt--library_panel))
29 | - `links` (Attributes List) Panel links. (see [below for nested schema](#nestedatt--links))
30 | - `max_data_points` (Number) The maximum number of data points that the panel queries are retrieving.
31 | - `options` (Attributes) (see [below for nested schema](#nestedatt--options))
32 | - `plugin_version` (String) The version of the plugin that is used for this panel. This is used to find the plugin to display the panel and to migrate old panel configs.
33 | - `repeat` (String) Name of template variable to repeat for.
34 | - `repeat_direction` (String) Direction to repeat in if 'repeat' is set.
35 | h for horizontal, v for vertical. Defaults to "h".
36 | - `repeat_panel_id` (Number) Id of the repeating panel.
37 | - `tags` (List of String) Tags for the panel.
38 | - `targets` (List of String) Depends on the panel plugin. See the plugin documentation for details.
39 | - `time_from` (String) Overrides the relative time range for individual panels,
40 | which causes them to be different than what is selected in
41 | the dashboard time picker in the top-right corner of the dashboard. You can use this to show metrics from different
42 | time periods or days on the same dashboard.
43 | The value is formatted as time operation like: now-5m (Last 5 minutes), now/d (the day so far),
44 | now-5d/d(Last 5 days), now/w (This week so far), now-2y/y (Last 2 years).
45 | Note: Panel time overrides have no effect when the dashboard’s time range is absolute.
46 | See: https://grafana.com/docs/grafana/latest/panels-visualizations/query-transform-data/#query-options
47 | - `time_shift` (String) Overrides the time range for individual panels by shifting its start and end relative to the time picker.
48 | For example, you can shift the time range for the panel to be two hours earlier than the dashboard time picker setting 2h.
49 | Note: Panel time overrides have no effect when the dashboard’s time range is absolute.
50 | See: https://grafana.com/docs/grafana/latest/panels-visualizations/query-transform-data/#query-options
51 | - `title` (String) Panel title.
52 | - `transformations` (Attributes List) List of transformations that are applied to the panel data before rendering.
53 | When there are multiple transformations, Grafana applies them in the order they are listed.
54 | Each transformation creates a result set that then passes on to the next transformation in the processing pipeline. (see [below for nested schema](#nestedatt--transformations))
55 | - `transparent` (Boolean) Whether to display the panel without a background. Defaults to false.
56 | - `type` (String) The panel plugin type id. This is used to find the plugin to display the panel. Defaults to "text".
57 |
58 | ### Read-Only
59 |
60 | - `rendered_json` (String) This datasource rendered as JSON
61 |
62 |
63 | ### Nested Schema for `datasource`
64 |
65 | Optional:
66 |
67 | - `type` (String) The plugin type-id
68 | - `uid` (String) Specific datasource instance
69 |
70 |
71 |
72 | ### Nested Schema for `field_config`
73 |
74 | Optional:
75 |
76 | - `defaults` (Attributes) Defaults are the options applied to all fields. (see [below for nested schema](#nestedatt--field_config--defaults))
77 | - `overrides` (Attributes List) Overrides are the options applied to specific fields overriding the defaults. (see [below for nested schema](#nestedatt--field_config--overrides))
78 |
79 |
80 | ### Nested Schema for `field_config.defaults`
81 |
82 | Optional:
83 |
84 | - `color` (Attributes) Panel color configuration (see [below for nested schema](#nestedatt--field_config--defaults--color))
85 | - `custom` (Attributes) (see [below for nested schema](#nestedatt--field_config--defaults--custom))
86 | - `decimals` (Number) Specify the number of decimals Grafana includes in the rendered value.
87 | If you leave this field blank, Grafana automatically truncates the number of decimals based on the value.
88 | For example 1.1234 will display as 1.12 and 100.456 will display as 100.
89 | To display all decimals, set the unit to String.
90 | - `description` (String) Human readable field metadata
91 | - `display_name` (String) The display value for this field. This supports template variables blank is auto
92 | - `display_name_from_ds` (String) This can be used by data sources that return and explicit naming structure for values and labels
93 | When this property is configured, this value is used rather than the default naming strategy.
94 | - `filterable` (Boolean) True if data source field supports ad-hoc filters
95 | - `mappings` (Attributes List) Convert input values into a display string (see [below for nested schema](#nestedatt--field_config--defaults--mappings))
96 | - `max` (Number) The maximum value used in percentage threshold calculations. Leave blank for auto calculation based on all series and fields.
97 | - `min` (Number) The minimum value used in percentage threshold calculations. Leave blank for auto calculation based on all series and fields.
98 | - `no_value` (String) Alternative to empty string
99 | - `path` (String) An explicit path to the field in the datasource. When the frame meta includes a path,
100 | This will default to ${frame.meta.path}/${field.name}
101 |
102 | When defined, this value can be used as an identifier within the datasource scope, and
103 | may be used to update the results
104 | - `thresholds` (Attributes) Map numeric values to states (see [below for nested schema](#nestedatt--field_config--defaults--thresholds))
105 | - `unit` (String) Unit a field should use. The unit you select is applied to all fields except time.
106 | You can use the units ID availables in Grafana or a custom unit.
107 | Available units in Grafana: https://github.com/grafana/grafana/blob/main/packages/grafana-data/src/valueFormats/categories.ts
108 | As custom unit, you can use the following formats:
109 | suffix: for custom unit that should go after value.
110 | prefix: for custom unit that should go before value.
111 | time: For custom date time formats type for example time:YYYY-MM-DD.
112 | si: for custom SI units. For example: si: mF. This one is a bit more advanced as you can specify both a unit and the source data scale. So if your source data is represented as milli (thousands of) something prefix the unit with that SI scale character.
113 | count: for a custom count unit.
114 | currency: for custom a currency unit.
115 | - `writeable` (Boolean) True if data source can write a value to the path. Auth/authz are supported separately
116 |
117 |
118 | ### Nested Schema for `field_config.defaults.color`
119 |
120 | Required:
121 |
122 | - `mode` (String) The main color scheme mode.
123 |
124 | Optional:
125 |
126 | - `fixed_color` (String) The fixed color value for fixed or shades color modes.
127 | - `series_by` (String) Some visualizations need to know how to assign a series color from by value color schemes.
128 |
129 |
130 |
131 | ### Nested Schema for `field_config.defaults.custom`
132 |
133 | Optional:
134 |
135 | - `fill_opacity` (Number) Defaults to 70.
136 | - `hide_from` (Attributes) (see [below for nested schema](#nestedatt--field_config--defaults--custom--hide_from))
137 | - `line_width` (Number) Defaults to 1.
138 |
139 |
140 | ### Nested Schema for `field_config.defaults.custom.line_width`
141 |
142 | Required:
143 |
144 | - `legend` (Boolean)
145 | - `tooltip` (Boolean)
146 | - `viz` (Boolean)
147 |
148 |
149 |
150 |
151 | ### Nested Schema for `field_config.defaults.mappings`
152 |
153 | Optional:
154 |
155 | - `range_map` (Attributes) (see [below for nested schema](#nestedatt--field_config--defaults--mappings--range_map))
156 | - `regex_map` (Attributes) (see [below for nested schema](#nestedatt--field_config--defaults--mappings--regex_map))
157 | - `special_value_map` (Attributes) (see [below for nested schema](#nestedatt--field_config--defaults--mappings--special_value_map))
158 | - `value_map` (Attributes) (see [below for nested schema](#nestedatt--field_config--defaults--mappings--value_map))
159 |
160 |
161 | ### Nested Schema for `field_config.defaults.mappings.value_map`
162 |
163 | Required:
164 |
165 | - `type` (String)
166 |
167 | Optional:
168 |
169 | - `options` (Attributes) Range to match against and the result to apply when the value is within the range (see [below for nested schema](#nestedatt--field_config--defaults--mappings--value_map--options))
170 |
171 |
172 | ### Nested Schema for `field_config.defaults.mappings.value_map.options`
173 |
174 | Required:
175 |
176 | - `from` (String) Min value of the range. It can be null which means -Infinity
177 | - `to` (String) Max value of the range. It can be null which means +Infinity
178 |
179 | Optional:
180 |
181 | - `result` (Attributes) Config to apply when the value is within the range (see [below for nested schema](#nestedatt--field_config--defaults--mappings--value_map--options--result))
182 |
183 |
184 | ### Nested Schema for `field_config.defaults.mappings.value_map.options.result`
185 |
186 | Optional:
187 |
188 | - `color` (String) Text to use when the value matches
189 | - `icon` (String) Icon to display when the value matches. Only specific visualizations.
190 | - `index` (Number) Position in the mapping array. Only used internally.
191 | - `text` (String) Text to display when the value matches
192 |
193 |
194 |
195 |
196 |
197 | ### Nested Schema for `field_config.defaults.mappings.value_map`
198 |
199 | Required:
200 |
201 | - `type` (String)
202 |
203 | Optional:
204 |
205 | - `options` (Attributes) Regular expression to match against and the result to apply when the value matches the regex (see [below for nested schema](#nestedatt--field_config--defaults--mappings--value_map--options))
206 |
207 |
208 | ### Nested Schema for `field_config.defaults.mappings.value_map.options`
209 |
210 | Required:
211 |
212 | - `pattern` (String) Regular expression to match against
213 |
214 | Optional:
215 |
216 | - `result` (Attributes) Config to apply when the value matches the regex (see [below for nested schema](#nestedatt--field_config--defaults--mappings--value_map--options--result))
217 |
218 |
219 | ### Nested Schema for `field_config.defaults.mappings.value_map.options.result`
220 |
221 | Optional:
222 |
223 | - `color` (String) Text to use when the value matches
224 | - `icon` (String) Icon to display when the value matches. Only specific visualizations.
225 | - `index` (Number) Position in the mapping array. Only used internally.
226 | - `text` (String) Text to display when the value matches
227 |
228 |
229 |
230 |
231 |
232 | ### Nested Schema for `field_config.defaults.mappings.value_map`
233 |
234 | Required:
235 |
236 | - `type` (String)
237 |
238 | Optional:
239 |
240 | - `options` (Attributes) (see [below for nested schema](#nestedatt--field_config--defaults--mappings--value_map--options))
241 |
242 |
243 | ### Nested Schema for `field_config.defaults.mappings.value_map.options`
244 |
245 | Required:
246 |
247 | - `match` (String) Special value to match against
248 |
249 | Optional:
250 |
251 | - `result` (Attributes) Config to apply when the value matches the special value (see [below for nested schema](#nestedatt--field_config--defaults--mappings--value_map--options--result))
252 |
253 |
254 | ### Nested Schema for `field_config.defaults.mappings.value_map.options.result`
255 |
256 | Optional:
257 |
258 | - `color` (String) Text to use when the value matches
259 | - `icon` (String) Icon to display when the value matches. Only specific visualizations.
260 | - `index` (Number) Position in the mapping array. Only used internally.
261 | - `text` (String) Text to display when the value matches
262 |
263 |
264 |
265 |
266 |
267 | ### Nested Schema for `field_config.defaults.mappings.value_map`
268 |
269 | Required:
270 |
271 | - `type` (String)
272 |
273 | Optional:
274 |
275 | - `options` (Attributes Map) Map with : ValueMappingResult. For example: { "10": { text: "Perfection!", color: "green" } } (see [below for nested schema](#nestedatt--field_config--defaults--mappings--value_map--options))
276 |
277 |
278 | ### Nested Schema for `field_config.defaults.mappings.value_map.options`
279 |
280 | Optional:
281 |
282 | - `color` (String) Text to use when the value matches
283 | - `icon` (String) Icon to display when the value matches. Only specific visualizations.
284 | - `index` (Number) Position in the mapping array. Only used internally.
285 | - `text` (String) Text to display when the value matches
286 |
287 |
288 |
289 |
290 |
291 | ### Nested Schema for `field_config.defaults.thresholds`
292 |
293 | Required:
294 |
295 | - `mode` (String) Thresholds mode.
296 |
297 | Optional:
298 |
299 | - `steps` (Attributes List) Must be sorted by 'value', first value is always -Infinity (see [below for nested schema](#nestedatt--field_config--defaults--thresholds--steps))
300 |
301 |
302 | ### Nested Schema for `field_config.defaults.thresholds.steps`
303 |
304 | Required:
305 |
306 | - `color` (String) Color represents the color of the visual change that will occur in the dashboard when the threshold value is met or exceeded.
307 | - `value` (String) Value represents a specified metric for the threshold, which triggers a visual change in the dashboard when this value is met or exceeded.
308 | Nulls currently appear here when serializing -Infinity to JSON.
309 |
310 |
311 |
312 |
313 |
314 | ### Nested Schema for `field_config.overrides`
315 |
316 | Optional:
317 |
318 | - `matcher` (Attributes) (see [below for nested schema](#nestedatt--field_config--overrides--matcher))
319 | - `properties` (Attributes List) (see [below for nested schema](#nestedatt--field_config--overrides--properties))
320 |
321 |
322 | ### Nested Schema for `field_config.overrides.matcher`
323 |
324 |
325 |
326 | ### Nested Schema for `field_config.overrides.properties`
327 |
328 |
329 |
330 |
331 |
332 | ### Nested Schema for `grid_pos`
333 |
334 | Optional:
335 |
336 | - `h` (Number) Panel height. The height is the number of rows from the top edge of the panel. Defaults to 9.
337 | - `static` (Boolean) Whether the panel is fixed within the grid. If true, the panel will not be affected by other panels' interactions
338 | - `w` (Number) Panel width. The width is the number of columns from the left edge of the panel. Defaults to 12.
339 | - `x` (Number) Panel x. The x coordinate is the number of columns from the left edge of the grid. Defaults to 0.
340 | - `y` (Number) Panel y. The y coordinate is the number of rows from the top edge of the grid. Defaults to 0.
341 |
342 |
343 |
344 | ### Nested Schema for `library_panel`
345 |
346 | Required:
347 |
348 | - `name` (String) Library panel name
349 | - `uid` (String) Library panel uid
350 |
351 |
352 |
353 | ### Nested Schema for `links`
354 |
355 | Required:
356 |
357 | - `icon` (String) Icon name to be displayed with the link
358 | - `title` (String) Title to display with the link
359 | - `tooltip` (String) Tooltip to display when the user hovers their mouse over it
360 | - `type` (String) Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource)
361 | - `url` (String) Link URL. Only required/valid if the type is link
362 |
363 | Optional:
364 |
365 | - `as_dropdown` (Boolean) If true, all dashboards links will be displayed in a dropdown. If false, all dashboards links will be displayed side by side. Only valid if the type is dashboards. Defaults to false.
366 | - `include_vars` (Boolean) If true, includes current template variables values in the link as query params. Defaults to false.
367 | - `keep_time` (Boolean) If true, includes current time range in the link as query params. Defaults to false.
368 | - `tags` (List of String) List of tags to limit the linked dashboards. If empty, all dashboards will be displayed. Only valid if the type is dashboards
369 | - `target_blank` (Boolean) If true, the link will be opened in a new tab. Defaults to false.
370 |
371 |
372 |
373 | ### Nested Schema for `options`
374 |
375 | Optional:
376 |
377 | - `code` (Attributes) (see [below for nested schema](#nestedatt--options--code))
378 | - `content` (String) Defaults to "# Title
379 |
380 | For markdown syntax help: [commonmark.org/help](https://commonmark.org/help/)".
381 | - `mode` (String) Defaults to "markdown".
382 |
383 |
384 | ### Nested Schema for `options.code`
385 |
386 | Optional:
387 |
388 | - `language` (String) The language passed to monaco code editor. Defaults to "plaintext".
389 | - `show_line_numbers` (Boolean) Defaults to false.
390 | - `show_mini_map` (Boolean) Defaults to false.
391 |
392 |
393 |
394 |
395 | ### Nested Schema for `transformations`
396 |
397 | Optional:
398 |
399 | - `disabled` (Boolean) Disabled transformations are skipped
400 | - `filter` (Attributes) Optional frame matcher. When missing it will be applied to all results (see [below for nested schema](#nestedatt--transformations--filter))
401 |
402 |
403 | ### Nested Schema for `transformations.filter`
404 |
--------------------------------------------------------------------------------