@intentius/chant-lexicon-grafana 0.98.0 → 0.100.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -8
- package/dist/actions/grafana.d.ts +24 -0
- package/dist/actions/grafana.d.ts.map +1 -0
- package/dist/actions/index.d.ts +2 -0
- package/dist/actions/index.d.ts.map +1 -0
- package/dist/alerting-build.d.ts +128 -0
- package/dist/alerting-build.d.ts.map +1 -0
- package/dist/alerting.d.ts +273 -0
- package/dist/alerting.d.ts.map +1 -0
- package/dist/annotations.d.ts +61 -0
- package/dist/annotations.d.ts.map +1 -0
- package/dist/api/apply.d.ts +160 -0
- package/dist/api/apply.d.ts.map +1 -0
- package/dist/api/bind.d.ts +32 -0
- package/dist/api/bind.d.ts.map +1 -0
- package/dist/api/client.d.ts +76 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/converge.d.ts +33 -0
- package/dist/api/converge.d.ts.map +1 -0
- package/dist/api/dashboards.d.ts +102 -0
- package/dist/api/dashboards.d.ts.map +1 -0
- package/dist/api/datasources.d.ts +26 -0
- package/dist/api/datasources.d.ts.map +1 -0
- package/dist/api/fake-grafana-writes.d.ts +41 -0
- package/dist/api/fake-grafana-writes.d.ts.map +1 -0
- package/dist/api/fake-grafana.d.ts +63 -0
- package/dist/api/fake-grafana.d.ts.map +1 -0
- package/dist/api/folders.d.ts +146 -0
- package/dist/api/folders.d.ts.map +1 -0
- package/dist/api/library-panels.d.ts +52 -0
- package/dist/api/library-panels.d.ts.map +1 -0
- package/dist/build.d.ts +55 -6
- package/dist/build.d.ts.map +1 -1
- package/dist/catalog.d.ts +1 -1
- package/dist/catalog.d.ts.map +1 -1
- package/dist/codegen/docs.d.ts.map +1 -1
- package/dist/codegen/generate.d.ts +7 -1
- package/dist/codegen/generate.d.ts.map +1 -1
- package/dist/codegen/schema-types.d.ts +3 -3
- package/dist/codegen/schema-types.d.ts.map +1 -1
- package/dist/composites/agent-dashboard.d.ts.map +1 -1
- package/dist/composites/catalog.d.ts.map +1 -1
- package/dist/composites/index.d.ts +4 -2
- package/dist/composites/index.d.ts.map +1 -1
- package/dist/composites/red-dashboard.d.ts +21 -2
- package/dist/composites/red-dashboard.d.ts.map +1 -1
- package/dist/composites/shared.d.ts +11 -3
- package/dist/composites/shared.d.ts.map +1 -1
- package/dist/composites/slo-alert-rules.d.ts +92 -0
- package/dist/composites/slo-alert-rules.d.ts.map +1 -0
- package/dist/config.d.ts +111 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/contact-point-secrets.d.ts +17 -0
- package/dist/contact-point-secrets.d.ts.map +1 -0
- package/dist/dashboard.d.ts +51 -9
- package/dist/dashboard.d.ts.map +1 -1
- package/dist/datasource-refs.d.ts +99 -0
- package/dist/datasource-refs.d.ts.map +1 -0
- package/dist/datasource-settings.d.ts +834 -0
- package/dist/datasource-settings.d.ts.map +1 -0
- package/dist/datasource.d.ts +82 -11
- package/dist/datasource.d.ts.map +1 -1
- package/dist/deep-observe-hooks.d.ts +64 -0
- package/dist/deep-observe-hooks.d.ts.map +1 -0
- package/dist/deep-observe.d.ts +47 -0
- package/dist/deep-observe.d.ts.map +1 -0
- package/dist/describe-resources.d.ts +50 -0
- package/dist/describe-resources.d.ts.map +1 -0
- package/dist/detect.d.ts +32 -3
- package/dist/detect.d.ts.map +1 -1
- package/dist/export-resources.d.ts +38 -0
- package/dist/export-resources.d.ts.map +1 -0
- package/dist/folder.d.ts +68 -0
- package/dist/folder.d.ts.map +1 -0
- package/dist/import/alerting.d.ts +40 -0
- package/dist/import/alerting.d.ts.map +1 -0
- package/dist/import/edits.d.ts +47 -0
- package/dist/import/edits.d.ts.map +1 -0
- package/dist/import/embedded.d.ts +14 -0
- package/dist/import/embedded.d.ts.map +1 -0
- package/dist/import/generator.d.ts +60 -0
- package/dist/import/generator.d.ts.map +1 -0
- package/dist/import/live-export.d.ts +108 -0
- package/dist/import/live-export.d.ts.map +1 -0
- package/dist/import/mappings.d.ts +89 -0
- package/dist/import/mappings.d.ts.map +1 -0
- package/dist/import/model.d.ts +105 -0
- package/dist/import/model.d.ts.map +1 -0
- package/dist/import/normalize-alerting.d.ts +26 -0
- package/dist/import/normalize-alerting.d.ts.map +1 -0
- package/dist/import/normalize.d.ts +74 -0
- package/dist/import/normalize.d.ts.map +1 -0
- package/dist/import/parser.d.ts +125 -0
- package/dist/import/parser.d.ts.map +1 -0
- package/dist/import/report.d.ts +26 -0
- package/dist/import/report.d.ts.map +1 -0
- package/dist/import/testdata/fixtures.d.ts +41 -0
- package/dist/import/testdata/fixtures.d.ts.map +1 -0
- package/dist/import/v2.d.ts +73 -0
- package/dist/import/v2.d.ts.map +1 -0
- package/dist/index.d.ts +31 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/init-templates.d.ts +27 -0
- package/dist/init-templates.d.ts.map +1 -0
- package/dist/integrity.json +22 -12
- package/dist/k8s.d.ts +107 -0
- package/dist/k8s.d.ts.map +1 -0
- package/dist/lint/audit-catalog.d.ts +2 -1
- package/dist/lint/audit-catalog.d.ts.map +1 -1
- package/dist/lint/post-synth/graf101.d.ts +2 -2
- package/dist/lint/post-synth/graf102.d.ts +1 -1
- package/dist/lint/post-synth/graf104.d.ts +2 -2
- package/dist/lint/post-synth/graf106.d.ts +2 -2
- package/dist/lint/post-synth/graf107.d.ts +1 -1
- package/dist/lint/post-synth/graf108.d.ts +8 -0
- package/dist/lint/post-synth/graf108.d.ts.map +1 -0
- package/dist/lint/post-synth/graf109.d.ts +8 -0
- package/dist/lint/post-synth/graf109.d.ts.map +1 -0
- package/dist/lint/post-synth/graf110.d.ts +8 -0
- package/dist/lint/post-synth/graf110.d.ts.map +1 -0
- package/dist/lint/post-synth/graf111.d.ts +8 -0
- package/dist/lint/post-synth/graf111.d.ts.map +1 -0
- package/dist/lint/post-synth/graf112.d.ts +8 -0
- package/dist/lint/post-synth/graf112.d.ts.map +1 -0
- package/dist/lint/post-synth/graf113.d.ts +8 -0
- package/dist/lint/post-synth/graf113.d.ts.map +1 -0
- package/dist/lint/post-synth/graf114.d.ts +8 -0
- package/dist/lint/post-synth/graf114.d.ts.map +1 -0
- package/dist/lint/post-synth/graf115.d.ts +8 -0
- package/dist/lint/post-synth/graf115.d.ts.map +1 -0
- package/dist/lint/post-synth/grafana-helpers.d.ts +7 -5
- package/dist/lint/post-synth/grafana-helpers.d.ts.map +1 -1
- package/dist/lint/post-synth/index.d.ts.map +1 -1
- package/dist/lint/rules/literal-secret.d.ts +7 -3
- package/dist/lint/rules/literal-secret.d.ts.map +1 -1
- package/dist/lsp/hover.d.ts.map +1 -1
- package/dist/manifest.json +1 -1
- package/dist/members.d.ts +27 -0
- package/dist/members.d.ts.map +1 -0
- package/dist/meta.json +205 -0
- package/dist/okf/index.md +53 -4
- package/dist/okf/rules/GRAF002.md +3 -2
- package/dist/okf/rules/GRAF101.md +3 -2
- package/dist/okf/rules/GRAF102.md +1 -0
- package/dist/okf/rules/GRAF104.md +2 -2
- package/dist/okf/rules/GRAF106.md +2 -2
- package/dist/okf/rules/GRAF108.md +11 -0
- package/dist/okf/rules/GRAF109.md +15 -0
- package/dist/okf/rules/GRAF110.md +11 -0
- package/dist/okf/rules/GRAF111.md +11 -0
- package/dist/okf/rules/GRAF112.md +16 -0
- package/dist/okf/rules/GRAF113.md +16 -0
- package/dist/okf/rules/GRAF114.md +11 -0
- package/dist/okf/rules/GRAF115.md +11 -0
- package/dist/okf/types/AdhocVariable.md +9 -0
- package/dist/okf/types/AlertListPanel.md +9 -0
- package/dist/okf/types/AlertQuery.md +9 -0
- package/dist/okf/types/AlertRule.md +9 -0
- package/dist/okf/types/AlertRuleGroup.md +9 -0
- package/dist/okf/types/AzureMonitorQuery.md +9 -0
- package/dist/okf/types/BarChartPanel.md +9 -0
- package/dist/okf/types/BarGaugePanel.md +9 -0
- package/dist/okf/types/BigQueryQuery.md +9 -0
- package/dist/okf/types/CanvasPanel.md +9 -0
- package/dist/okf/types/ClassicConditionsExpression.md +9 -0
- package/dist/okf/types/CloudMonitoringQuery.md +9 -0
- package/dist/okf/types/CloudWatchQuery.md +9 -0
- package/dist/okf/types/ContactPoint.md +14 -0
- package/dist/okf/types/Dashboard.md +2 -1
- package/dist/okf/types/Datasource.md +3 -2
- package/dist/okf/types/DatasourceProvisioning.md +9 -0
- package/dist/okf/types/ElasticsearchQuery.md +9 -0
- package/dist/okf/types/ExternalDatasource.md +15 -0
- package/dist/okf/types/FlameGraphPanel.md +9 -0
- package/dist/okf/types/Folder.md +9 -0
- package/dist/okf/types/GeomapPanel.md +9 -0
- package/dist/okf/types/GroupByVariable.md +9 -0
- package/dist/okf/types/HistogramPanel.md +9 -0
- package/dist/okf/types/MSSQLQuery.md +9 -0
- package/dist/okf/types/MathExpression.md +9 -0
- package/dist/okf/types/MuteTiming.md +13 -0
- package/dist/okf/types/MySQLQuery.md +9 -0
- package/dist/okf/types/NodeGraphPanel.md +9 -0
- package/dist/okf/types/NotificationPolicy.md +9 -0
- package/dist/okf/types/NotificationTemplate.md +9 -0
- package/dist/okf/types/PieChartPanel.md +9 -0
- package/dist/okf/types/PostgresQuery.md +9 -0
- package/dist/okf/types/PyroscopeQuery.md +9 -0
- package/dist/okf/types/ReduceExpression.md +9 -0
- package/dist/okf/types/ResampleExpression.md +9 -0
- package/dist/okf/types/SqlExpression.md +9 -0
- package/dist/okf/types/StateTimelinePanel.md +9 -0
- package/dist/okf/types/StatusHistoryPanel.md +9 -0
- package/dist/okf/types/SwitchVariable.md +9 -0
- package/dist/okf/types/ThresholdExpression.md +9 -0
- package/dist/okf/types/TrendPanel.md +9 -0
- package/dist/okf/types/XYChartPanel.md +9 -0
- package/dist/op/activities/grafana-apply.d.ts +86 -0
- package/dist/op/activities/grafana-apply.d.ts.map +1 -0
- package/dist/op/activities/index.d.ts +9 -0
- package/dist/op/activities/index.d.ts.map +1 -0
- package/dist/op/builders.d.ts +24 -0
- package/dist/op/builders.d.ts.map +1 -0
- package/dist/ownership.d.ts +78 -0
- package/dist/ownership.d.ts.map +1 -0
- package/dist/panel-options.d.ts +65 -0
- package/dist/panel-options.d.ts.map +1 -0
- package/dist/panels.d.ts +46 -9
- package/dist/panels.d.ts.map +1 -1
- package/dist/pin.d.ts +29 -7
- package/dist/pin.d.ts.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/promql-check.d.ts +51 -0
- package/dist/promql-check.d.ts.map +1 -0
- package/dist/query-models.d.ts +95 -0
- package/dist/query-models.d.ts.map +1 -0
- package/dist/query.d.ts +116 -18
- package/dist/query.d.ts.map +1 -1
- package/dist/rules/graf101.ts +3 -3
- package/dist/rules/graf102.ts +1 -1
- package/dist/rules/graf104.ts +3 -3
- package/dist/rules/graf106.ts +3 -3
- package/dist/rules/graf107.ts +1 -1
- package/dist/rules/graf108.ts +17 -0
- package/dist/rules/graf109.ts +17 -0
- package/dist/rules/graf110.ts +17 -0
- package/dist/rules/graf111.ts +17 -0
- package/dist/rules/graf112.ts +17 -0
- package/dist/rules/graf113.ts +17 -0
- package/dist/rules/graf114.ts +17 -0
- package/dist/rules/graf115.ts +17 -0
- package/dist/rules/grafana-helpers.ts +27 -10
- package/dist/rules/literal-secret.ts +60 -6
- package/dist/schema/azuremonitor.gen.d.ts +354 -0
- package/dist/schema/azuremonitor.gen.d.ts.map +1 -0
- package/dist/schema/barchart.gen.d.ts +198 -0
- package/dist/schema/barchart.gen.d.ts.map +1 -0
- package/dist/schema/bargauge.gen.d.ts +97 -0
- package/dist/schema/bargauge.gen.d.ts.map +1 -0
- package/dist/schema/bigquery.gen.d.ts +93 -0
- package/dist/schema/bigquery.gen.d.ts.map +1 -0
- package/dist/schema/canvas.gen.d.ts +152 -0
- package/dist/schema/canvas.gen.d.ts.map +1 -0
- package/dist/schema/cloudwatch.gen.d.ts +394 -0
- package/dist/schema/cloudwatch.gen.d.ts.map +1 -0
- package/dist/schema/dashboard.gen.d.ts +196 -21
- package/dist/schema/dashboard.gen.d.ts.map +1 -1
- package/dist/schema/elasticsearch.gen.d.ts +444 -0
- package/dist/schema/elasticsearch.gen.d.ts.map +1 -0
- package/dist/schema/expr.gen.d.ts +606 -0
- package/dist/schema/expr.gen.d.ts.map +1 -0
- package/dist/schema/gauge.gen.d.ts.map +1 -1
- package/dist/schema/geomap.gen.d.ts +100 -0
- package/dist/schema/geomap.gen.d.ts.map +1 -0
- package/dist/schema/googlecloudmonitoring.gen.d.ts +312 -0
- package/dist/schema/googlecloudmonitoring.gen.d.ts.map +1 -0
- package/dist/schema/grafanapyroscope.gen.d.ts +60 -0
- package/dist/schema/grafanapyroscope.gen.d.ts.map +1 -0
- package/dist/schema/heatmap.gen.d.ts.map +1 -1
- package/dist/schema/histogram.gen.d.ts +132 -0
- package/dist/schema/histogram.gen.d.ts.map +1 -0
- package/dist/schema/index.d.ts +18 -0
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/logs.gen.d.ts +1 -0
- package/dist/schema/logs.gen.d.ts.map +1 -1
- package/dist/schema/loki.gen.d.ts.map +1 -1
- package/dist/schema/nodegraph.gen.d.ts +49 -0
- package/dist/schema/nodegraph.gen.d.ts.map +1 -0
- package/dist/schema/piechart.gen.d.ts +127 -0
- package/dist/schema/piechart.gen.d.ts.map +1 -0
- package/dist/schema/prometheus.gen.d.ts.map +1 -1
- package/dist/schema/stat.gen.d.ts.map +1 -1
- package/dist/schema/statetimeline.gen.d.ts +124 -0
- package/dist/schema/statetimeline.gen.d.ts.map +1 -0
- package/dist/schema/statushistory.gen.d.ts +114 -0
- package/dist/schema/statushistory.gen.d.ts.map +1 -0
- package/dist/schema/table.gen.d.ts +35 -3
- package/dist/schema/table.gen.d.ts.map +1 -1
- package/dist/schema/tempo.gen.d.ts.map +1 -1
- package/dist/schema/text.gen.d.ts.map +1 -1
- package/dist/schema/timeseries.gen.d.ts +5 -1
- package/dist/schema/timeseries.gen.d.ts.map +1 -1
- package/dist/schema/trend.gen.d.ts +180 -0
- package/dist/schema/trend.gen.d.ts.map +1 -0
- package/dist/schema/xychart.gen.d.ts +145 -0
- package/dist/schema/xychart.gen.d.ts.map +1 -0
- package/dist/schema-validate.d.ts +39 -4
- package/dist/schema-validate.d.ts.map +1 -1
- package/dist/serializer.d.ts +11 -3
- package/dist/serializer.d.ts.map +1 -1
- package/dist/skill-defs.d.ts.map +1 -1
- package/dist/skills/chant-grafana-alerting.md +49 -0
- package/dist/skills/chant-grafana-operations.md +108 -0
- package/dist/skills/chant-grafana-provisioning.md +3 -3
- package/dist/skills/chant-grafana.md +15 -8
- package/dist/spec/fetch-units-cli.d.ts +3 -0
- package/dist/spec/fetch-units-cli.d.ts.map +1 -0
- package/dist/spec/overlay.d.ts +43 -0
- package/dist/spec/overlay.d.ts.map +1 -0
- package/dist/spec/schemas.d.ts +21 -13
- package/dist/spec/schemas.d.ts.map +1 -1
- package/dist/spec/schemas.gen.d.ts +3 -0
- package/dist/spec/schemas.gen.d.ts.map +1 -0
- package/dist/spec/units.d.ts +35 -0
- package/dist/spec/units.d.ts.map +1 -0
- package/dist/spec/units.gen.d.ts +2 -0
- package/dist/spec/units.gen.d.ts.map +1 -0
- package/dist/transformations.d.ts +459 -0
- package/dist/transformations.d.ts.map +1 -0
- package/dist/util.d.ts +6 -0
- package/dist/util.d.ts.map +1 -1
- package/dist/validate-alerting.d.ts +65 -0
- package/dist/validate-alerting.d.ts.map +1 -0
- package/dist/validate-output.d.ts +62 -9
- package/dist/validate-output.d.ts.map +1 -1
- package/dist/validate.d.ts.map +1 -1
- package/dist/validation.d.ts +14 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/variables.d.ts +109 -7
- package/dist/variables.d.ts.map +1 -1
- package/package.json +12 -4
- package/src/actions/actions.test.ts +24 -0
- package/src/actions/grafana.ts +40 -0
- package/src/actions/index.ts +1 -0
- package/src/alerting-build.ts +376 -0
- package/src/alerting.e2e.test.ts +212 -0
- package/src/alerting.test.ts +272 -0
- package/src/alerting.ts +435 -0
- package/src/annotations.ts +84 -0
- package/src/api/apply.test.ts +256 -0
- package/src/api/apply.ts +394 -0
- package/src/api/bind.ts +58 -0
- package/src/api/client.ts +148 -0
- package/src/api/converge.ts +63 -0
- package/src/api/dashboards.ts +247 -0
- package/src/api/datasources.ts +33 -0
- package/src/api/fake-grafana-writes.ts +201 -0
- package/src/api/fake-grafana.ts +190 -0
- package/src/api/folders.ts +339 -0
- package/src/api/library-panels.ts +101 -0
- package/src/build.test.ts +351 -10
- package/src/build.ts +294 -55
- package/src/catalog.ts +104 -2
- package/src/codegen/docs.ts +50 -10
- package/src/codegen/generate.ts +27 -1
- package/src/codegen/schema-types.ts +16 -6
- package/src/composites/agent-dashboard.ts +6 -3
- package/src/composites/catalog.test.ts +2 -2
- package/src/composites/catalog.ts +82 -0
- package/src/composites/composites.test.ts +73 -9
- package/src/composites/index.ts +4 -2
- package/src/composites/queries.e2e.test.ts +374 -0
- package/src/composites/red-dashboard.ts +83 -12
- package/src/composites/shared.ts +14 -2
- package/src/composites/slo-alert-rules.ts +149 -0
- package/src/config.test.ts +61 -0
- package/src/config.ts +138 -0
- package/src/contact-point-secrets.ts +63 -0
- package/src/dashboard.ts +68 -9
- package/src/datasource-refs.test.ts +56 -0
- package/src/datasource-refs.ts +213 -0
- package/src/datasource-settings.test.ts +106 -0
- package/src/datasource-settings.ts +941 -0
- package/src/datasource.ts +123 -11
- package/src/deep-observe-hooks.ts +267 -0
- package/src/deep-observe.test.ts +311 -0
- package/src/deep-observe.ts +187 -0
- package/src/describe-resources.test.ts +271 -0
- package/src/describe-resources.ts +244 -0
- package/src/detect.ts +82 -5
- package/src/export-resources.test.ts +129 -0
- package/src/export-resources.ts +84 -0
- package/src/folder.ts +118 -0
- package/src/generated/lexicon-grafana.json +205 -0
- package/src/import/alerting-roundtrip.test.ts +161 -0
- package/src/import/alerting.ts +500 -0
- package/src/import/edits.ts +95 -0
- package/src/import/embedded.test.ts +45 -0
- package/src/import/embedded.ts +47 -0
- package/src/import/generated-types.e2e.test.ts +130 -0
- package/src/import/generator.test.ts +210 -0
- package/src/import/generator.ts +463 -0
- package/src/import/live-export.ts +264 -0
- package/src/import/mappings.ts +336 -0
- package/src/import/model.ts +117 -0
- package/src/import/normalize-alerting.ts +101 -0
- package/src/import/normalize.test.ts +117 -0
- package/src/import/normalize.ts +393 -0
- package/src/import/parser.test.ts +516 -0
- package/src/import/parser.ts +1387 -0
- package/src/import/report.ts +62 -0
- package/src/import/roundtrip.test.ts +563 -0
- package/src/import/testdata/fixtures.ts +137 -0
- package/src/import/v2.test.ts +292 -0
- package/src/import/v2.ts +804 -0
- package/src/import.e2e.test.ts +31 -84
- package/src/import.test.ts +9 -3
- package/src/index.ts +308 -14
- package/src/init-templates.test.ts +74 -0
- package/src/init-templates.ts +349 -0
- package/src/k8s.test.ts +98 -0
- package/src/k8s.ts +197 -0
- package/src/lint/audit-catalog.ts +68 -3
- package/src/lint/core-lint.test.ts +43 -0
- package/src/lint/post-synth/graf101.ts +3 -3
- package/src/lint/post-synth/graf102.ts +1 -1
- package/src/lint/post-synth/graf104.ts +3 -3
- package/src/lint/post-synth/graf106.ts +3 -3
- package/src/lint/post-synth/graf107.ts +1 -1
- package/src/lint/post-synth/graf108.ts +17 -0
- package/src/lint/post-synth/graf109.ts +17 -0
- package/src/lint/post-synth/graf110.ts +17 -0
- package/src/lint/post-synth/graf111.ts +17 -0
- package/src/lint/post-synth/graf112.ts +17 -0
- package/src/lint/post-synth/graf113.ts +17 -0
- package/src/lint/post-synth/graf114.ts +17 -0
- package/src/lint/post-synth/graf115.ts +17 -0
- package/src/lint/post-synth/grafana-helpers.ts +27 -10
- package/src/lint/post-synth/index.ts +16 -0
- package/src/lint/post-synth/post-synth.test.ts +333 -12
- package/src/lint/rules/literal-secret.ts +60 -6
- package/src/lint/rules/rules.test.ts +27 -0
- package/src/load-cost.test.ts +35 -0
- package/src/lsp/completions.test.ts +5 -0
- package/src/lsp/hover.test.ts +7 -0
- package/src/lsp/hover.ts +8 -1
- package/src/members.ts +68 -0
- package/src/observe.e2e.test.ts +255 -0
- package/src/op/activities/grafana-apply.e2e.test.ts +184 -0
- package/src/op/activities/grafana-apply.test.ts +243 -0
- package/src/op/activities/grafana-apply.ts +197 -0
- package/src/op/activities/index.ts +8 -0
- package/src/op/builders.test.ts +40 -0
- package/src/op/builders.ts +34 -0
- package/src/ownership.ts +122 -0
- package/src/panel-options.ts +66 -0
- package/src/panels.test.ts +53 -0
- package/src/panels.ts +148 -10
- package/src/pin.ts +69 -6
- package/src/plugin.test.ts +12 -2
- package/src/plugin.ts +75 -0
- package/src/promql-check.test.ts +108 -0
- package/src/promql-check.ts +193 -0
- package/src/query-models.ts +94 -0
- package/src/query.test.ts +166 -0
- package/src/query.ts +190 -20
- package/src/schema/azuremonitor.gen.ts +381 -0
- package/src/schema/barchart.gen.ts +221 -0
- package/src/schema/bargauge.gen.ts +111 -0
- package/src/schema/bigquery.gen.ts +110 -0
- package/src/schema/canvas.gen.ts +176 -0
- package/src/schema/cloudwatch.gen.ts +423 -0
- package/src/schema/dashboard.gen.ts +206 -22
- package/src/schema/elasticsearch.gen.ts +508 -0
- package/src/schema/expr.gen.ts +618 -0
- package/src/schema/gauge.gen.ts +2 -1
- package/src/schema/geomap.gen.ts +112 -0
- package/src/schema/googlecloudmonitoring.gen.ts +330 -0
- package/src/schema/grafanapyroscope.gen.ts +66 -0
- package/src/schema/heatmap.gen.ts +2 -1
- package/src/schema/histogram.gen.ts +151 -0
- package/src/schema/index.ts +18 -0
- package/src/schema/logs.gen.ts +3 -1
- package/src/schema/loki.gen.ts +2 -1
- package/src/schema/nodegraph.gen.ts +58 -0
- package/src/schema/piechart.gen.ts +146 -0
- package/src/schema/prometheus.gen.ts +2 -1
- package/src/schema/stat.gen.ts +2 -1
- package/src/schema/statetimeline.gen.ts +143 -0
- package/src/schema/statushistory.gen.ts +132 -0
- package/src/schema/table.gen.ts +41 -4
- package/src/schema/tempo.gen.ts +2 -1
- package/src/schema/text.gen.ts +2 -1
- package/src/schema/timeseries.gen.ts +7 -2
- package/src/schema/trend.gen.ts +208 -0
- package/src/schema/xychart.gen.ts +167 -0
- package/src/schema-overlay.test.ts +282 -0
- package/src/schema-validate.ts +199 -57
- package/src/schema.test.ts +4 -2
- package/src/serializer.test.ts +13 -1
- package/src/serializer.ts +11 -3
- package/src/skill-defs.ts +34 -0
- package/src/skills/chant-grafana-alerting.md +49 -0
- package/src/skills/chant-grafana-operations.md +108 -0
- package/src/skills/chant-grafana-provisioning.md +3 -3
- package/src/skills/chant-grafana.md +15 -8
- package/src/spec/fetch-cli.ts +3 -3
- package/src/spec/fetch-units-cli.ts +37 -0
- package/src/spec/overlay/canvas.overlay.json +142 -0
- package/src/spec/overlay/dashboard.overlay.json +378 -0
- package/src/spec/overlay/expr.overlay.json +14 -0
- package/src/spec/overlay/geomap.overlay.json +35 -0
- package/src/spec/overlay/logs.overlay.json +14 -0
- package/src/spec/overlay/nodegraph.overlay.json +31 -0
- package/src/spec/overlay/piechart.overlay.json +17 -0
- package/src/spec/overlay/table.overlay.json +103 -0
- package/src/spec/overlay/timeseries.overlay.json +21 -0
- package/src/spec/overlay/trend.overlay.json +17 -0
- package/src/spec/overlay/xychart.overlay.json +16 -0
- package/src/spec/overlay.ts +105 -0
- package/src/spec/schemas/azuremonitor.jsonschema.json +679 -0
- package/src/spec/schemas/barchart.jsonschema.json +419 -0
- package/src/spec/schemas/bargauge.jsonschema.json +224 -0
- package/src/spec/schemas/bigquery.jsonschema.json +290 -0
- package/src/spec/schemas/canvas.jsonschema.json +356 -0
- package/src/spec/schemas/cloudwatch.jsonschema.json +721 -0
- package/src/spec/schemas/dashboardv2.jsonschema.json +3387 -0
- package/src/spec/schemas/elasticsearch.jsonschema.json +1695 -0
- package/src/spec/schemas/expr.jsonschema.json +987 -0
- package/src/spec/schemas/geomap.jsonschema.json +220 -0
- package/src/spec/schemas/googlecloudmonitoring.jsonschema.json +488 -0
- package/src/spec/schemas/grafanapyroscope.jsonschema.json +93 -0
- package/src/spec/schemas/histogram.jsonschema.json +308 -0
- package/src/spec/schemas/nodegraph.jsonschema.json +77 -0
- package/src/spec/schemas/piechart.jsonschema.json +275 -0
- package/src/spec/schemas/statetimeline.jsonschema.json +324 -0
- package/src/spec/schemas/statushistory.jsonschema.json +292 -0
- package/src/spec/schemas/trend.jsonschema.json +449 -0
- package/src/spec/schemas/xychart.jsonschema.json +428 -0
- package/src/spec/schemas.gen.ts +40 -0
- package/src/spec/schemas.ts +30 -16
- package/src/spec/units.gen.ts +281 -0
- package/src/spec/units.ts +77 -0
- package/src/transformations.test.ts +65 -0
- package/src/transformations.ts +574 -0
- package/src/util.ts +8 -0
- package/src/validate-alerting.test.ts +255 -0
- package/src/validate-alerting.ts +430 -0
- package/src/validate-output.ts +427 -104
- package/src/validate.ts +28 -0
- package/src/validation.ts +27 -0
- package/src/variables.ts +120 -8
package/src/datasource.ts
CHANGED
|
@@ -10,9 +10,14 @@
|
|
|
10
10
|
import { createResource } from "@intentius/chant/runtime";
|
|
11
11
|
import type { Declarable } from "@intentius/chant/declarable";
|
|
12
12
|
import { slugUid } from "./util";
|
|
13
|
+
import type { DatasourceJsonData, DatasourceSecureJsonData, TypedDatasourceType } from "./datasource-settings";
|
|
13
14
|
|
|
14
|
-
/**
|
|
15
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Datasource plugin types this lexicon types queries and settings for
|
|
17
|
+
* (`postgres` is the PostgreSQL plugin's old id). Any other plugin id is
|
|
18
|
+
* accepted as a string.
|
|
19
|
+
*/
|
|
20
|
+
export type KnownDatasourceType = TypedDatasourceType;
|
|
16
21
|
|
|
17
22
|
/** How Grafana reaches the datasource: through its backend (`proxy`) or from the browser (`direct`). */
|
|
18
23
|
export type DatasourceAccess = "proxy" | "direct";
|
|
@@ -20,7 +25,7 @@ export type DatasourceAccess = "proxy" | "direct";
|
|
|
20
25
|
export interface DatasourceProps<T extends string = string> {
|
|
21
26
|
/** Display name, unique within the Grafana organisation. */
|
|
22
27
|
name: string;
|
|
23
|
-
/** The datasource plugin id, e.g. `prometheus`, `tempo`, `loki`. */
|
|
28
|
+
/** The datasource plugin id, e.g. `prometheus`, `tempo`, `loki`, `grafana-postgresql-datasource`. */
|
|
24
29
|
type: T;
|
|
25
30
|
/** Stable id panels refer to. Defaults to the name as a uid (`Prometheus` becomes `prometheus`). */
|
|
26
31
|
uid?: string;
|
|
@@ -33,17 +38,20 @@ export interface DatasourceProps<T extends string = string> {
|
|
|
33
38
|
database?: string;
|
|
34
39
|
withCredentials?: boolean;
|
|
35
40
|
/**
|
|
36
|
-
* Plugin settings
|
|
37
|
-
*
|
|
38
|
-
*
|
|
41
|
+
* Plugin settings, typed for the plugins in `DatasourceJsonDataTypes`
|
|
42
|
+
* (`./datasource-settings.ts`) and any object for others. A declared
|
|
43
|
+
* `Datasource` anywhere in here is written as its uid, so
|
|
44
|
+
* `tracesToLogsV2: { datasourceUid: loki }` links Tempo to a declared Loki;
|
|
45
|
+
* a typed field that names a datasource accepts only the plugin types
|
|
46
|
+
* Grafana offers there.
|
|
39
47
|
*/
|
|
40
|
-
jsonData?:
|
|
48
|
+
jsonData?: DatasourceJsonData<T>;
|
|
41
49
|
/**
|
|
42
|
-
* Secrets. Write them as Grafana provisioning
|
|
43
|
-
* (`$__env{NAME}`, `$__file{/path}`, `${NAME}`), not as
|
|
44
|
-
* flags a literal.
|
|
50
|
+
* Secrets, by the keys the plugin reads. Write them as Grafana provisioning
|
|
51
|
+
* expands them (`$__env{NAME}`, `$__file{/path}`, `${NAME}`), not as
|
|
52
|
+
* literals: GRAF002 flags a literal.
|
|
45
53
|
*/
|
|
46
|
-
secureJsonData?:
|
|
54
|
+
secureJsonData?: DatasourceSecureJsonData<T>;
|
|
47
55
|
/** Whether users may edit the provisioned datasource in the UI. Defaults to false. */
|
|
48
56
|
editable?: boolean;
|
|
49
57
|
orgId?: number;
|
|
@@ -83,6 +91,58 @@ export function isDatasourceEntity(value: unknown): value is DatasourceEntity {
|
|
|
83
91
|
);
|
|
84
92
|
}
|
|
85
93
|
|
|
94
|
+
export const EXTERNAL_DATASOURCE_TYPE = "Grafana::ExternalDatasource";
|
|
95
|
+
|
|
96
|
+
export interface ExternalDatasourceProps<T extends string = string> {
|
|
97
|
+
/** The datasource plugin id, e.g. `prometheus`. */
|
|
98
|
+
type: T;
|
|
99
|
+
/** The uid the datasource already has in Grafana. */
|
|
100
|
+
uid: string;
|
|
101
|
+
/** Its display name in Grafana, for messages and for a `DatasourceVariable` `regex`. */
|
|
102
|
+
name?: string;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export interface ExternalDatasourceEntity<T extends string = string> extends Declarable {
|
|
106
|
+
readonly props: ExternalDatasourceProps<T>;
|
|
107
|
+
/** The plugin id. */
|
|
108
|
+
readonly datasourceType: T;
|
|
109
|
+
/** The uid panels will reference. */
|
|
110
|
+
readonly uid: string;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const ExternalBase = createResource(EXTERNAL_DATASOURCE_TYPE, "grafana", {}) as unknown as (this: object, props: Record<string, unknown>) => void;
|
|
114
|
+
|
|
115
|
+
export interface ExternalDatasourceConstructor {
|
|
116
|
+
new <T extends string>(props: ExternalDatasourceProps<T>): ExternalDatasourceEntity<T>;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* A datasource that already exists in Grafana: provisioned by hand, by
|
|
121
|
+
* another build root, or by another tool. It is never written to the
|
|
122
|
+
* provisioning file. Panels, queries and variables use it like a
|
|
123
|
+
* `Datasource`, and GRAF101/GRAF102 check references against it.
|
|
124
|
+
*/
|
|
125
|
+
export const ExternalDatasource = function (this: object, props: ExternalDatasourceProps) {
|
|
126
|
+
ExternalBase.call(this, props as unknown as Record<string, unknown>);
|
|
127
|
+
Object.defineProperty(this, "datasourceType", { value: props.type, enumerable: false });
|
|
128
|
+
Object.defineProperty(this, "uid", { value: props.uid, enumerable: false });
|
|
129
|
+
} as unknown as ExternalDatasourceConstructor;
|
|
130
|
+
Object.defineProperty(ExternalDatasource, "name", { value: "ExternalDatasource" });
|
|
131
|
+
|
|
132
|
+
export function isExternalDatasource(value: unknown): value is ExternalDatasourceEntity {
|
|
133
|
+
return (
|
|
134
|
+
typeof value === "object" &&
|
|
135
|
+
value !== null &&
|
|
136
|
+
(value as Declarable).entityType === EXTERNAL_DATASOURCE_TYPE &&
|
|
137
|
+
(value as Declarable).lexicon === "grafana"
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/** A declared or an external datasource: anything a panel can hold that has a fixed uid. */
|
|
142
|
+
export function isDatasourceDeclaration(value: unknown): value is DatasourceEntity | ExternalDatasourceEntity {
|
|
143
|
+
return isDatasourceEntity(value) || isExternalDatasource(value);
|
|
144
|
+
}
|
|
145
|
+
|
|
86
146
|
/** A datasource declared somewhere this build can't see, named by its Grafana ref. */
|
|
87
147
|
export interface DatasourceRef<T extends string = string> {
|
|
88
148
|
type: T;
|
|
@@ -91,3 +151,55 @@ export interface DatasourceRef<T extends string = string> {
|
|
|
91
151
|
|
|
92
152
|
/** Grafana's own pseudo-datasources, which need no declaration. */
|
|
93
153
|
export const BUILTIN_DATASOURCE_UIDS: ReadonlySet<string> = new Set(["grafana", "-- Grafana --", "-- Mixed --", "-- Dashboard --"]);
|
|
154
|
+
|
|
155
|
+
export const DATASOURCE_PROVISIONING_TYPE = "Grafana::DatasourceProvisioning";
|
|
156
|
+
|
|
157
|
+
/** A datasource the provisioning file deletes, by its name in an organisation. */
|
|
158
|
+
export interface DeletedDatasource {
|
|
159
|
+
name: string;
|
|
160
|
+
/** Defaults to 1, as in Grafana. */
|
|
161
|
+
orgId?: number;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export interface DatasourceProvisioningProps {
|
|
165
|
+
/**
|
|
166
|
+
* Written as the file's `prune`. Grafana marks every datasource this file
|
|
167
|
+
* provisions as prunable, and deletes a prunable datasource once no
|
|
168
|
+
* provisioning file lists it any more, so removing a `Datasource` removes
|
|
169
|
+
* it from Grafana on the next provisioning run. Datasources provisioned
|
|
170
|
+
* without it, or made in the UI or API, are never pruned. Defaults to
|
|
171
|
+
* true; set false to keep a removed datasource in Grafana.
|
|
172
|
+
*/
|
|
173
|
+
prune?: boolean;
|
|
174
|
+
/**
|
|
175
|
+
* Written as the file's `deleteDatasources`: Grafana deletes these by name
|
|
176
|
+
* before it provisions the file's datasources. Name one the file also
|
|
177
|
+
* provisions to have Grafana re-create it from the file on every run.
|
|
178
|
+
*/
|
|
179
|
+
deleteDatasources?: DeletedDatasource[];
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export interface DatasourceProvisioningEntity extends Declarable {
|
|
183
|
+
readonly props: DatasourceProvisioningProps;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const ProvisioningBase = createResource(DATASOURCE_PROVISIONING_TYPE, "grafana", {}) as unknown as (this: object, props: Record<string, unknown>) => void;
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* The settings of the datasource provisioning file itself: `prune` and
|
|
190
|
+
* `deleteDatasources`. Optional: without one the file prunes. Declare at
|
|
191
|
+
* most one per build.
|
|
192
|
+
*/
|
|
193
|
+
export const DatasourceProvisioning = function (this: object, props: DatasourceProvisioningProps) {
|
|
194
|
+
ProvisioningBase.call(this, props as unknown as Record<string, unknown>);
|
|
195
|
+
} as unknown as new (props: DatasourceProvisioningProps) => DatasourceProvisioningEntity;
|
|
196
|
+
Object.defineProperty(DatasourceProvisioning, "name", { value: "DatasourceProvisioning" });
|
|
197
|
+
|
|
198
|
+
export function isDatasourceProvisioningEntity(value: unknown): value is DatasourceProvisioningEntity {
|
|
199
|
+
return (
|
|
200
|
+
typeof value === "object" &&
|
|
201
|
+
value !== null &&
|
|
202
|
+
(value as Declarable).entityType === DATASOURCE_PROVISIONING_TYPE &&
|
|
203
|
+
(value as Declarable).lexicon === "grafana"
|
|
204
|
+
);
|
|
205
|
+
}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* grafana deep-observation noise rules (#2946).
|
|
3
|
+
*
|
|
4
|
+
* Plain data on the plugin, because core applies the same rules to the
|
|
5
|
+
* declared tree (a `Dashboard`'s props, panels and queries inlined), which
|
|
6
|
+
* no reader touches. The live tree is the stored dashboard put back into the
|
|
7
|
+
* same vocabulary by the importer (./import/live-export.ts), so what is left
|
|
8
|
+
* to name here is what the translation cannot decide: values the build
|
|
9
|
+
* wrote that the author did not, values Grafana adds or drops on save, and
|
|
10
|
+
* values an author wrote out that are also what happens when they are left
|
|
11
|
+
* out.
|
|
12
|
+
*
|
|
13
|
+
* Measured against Grafana 12.4.11 and 13.2.2 (the e2e in
|
|
14
|
+
* ./observe.e2e.test.ts): read over `/api/dashboards/uid`, a stored dashboard
|
|
15
|
+
* differs from the built one only by the `id` and `version` Grafana adds
|
|
16
|
+
* (../test/e2e/stored-model.ts). Read over `/apis/dashboard.grafana.app`, its
|
|
17
|
+
* spec has no `id` or `version`, but it carries the built-in "Annotations &
|
|
18
|
+
* Alerts" annotation, and empty `options` and `fieldConfig` and every `null`
|
|
19
|
+
* are gone. The rest of this table is the build's own choices: panel ids,
|
|
20
|
+
* grid positions, query refIds, a panel's datasource taken from its queries.
|
|
21
|
+
*
|
|
22
|
+
* Every rule is one of four kinds, and they are in this order below:
|
|
23
|
+
*
|
|
24
|
+
* 1. **Never compared**, on either side: Grafana's bookkeeping.
|
|
25
|
+
* 2. **Empty is absent**, on both sides: `null`, `{}` and `[]` mean the same
|
|
26
|
+
* as leaving a key out, everywhere in a dashboard or datasource. The cost
|
|
27
|
+
* is that values added where the declaration wrote `[]` are reported as
|
|
28
|
+
* unclaimed rather than as drift.
|
|
29
|
+
* 3. **Build-derived**, on the live side where the declaration has nothing:
|
|
30
|
+
* the build filled it in, so it cannot disagree with what was declared.
|
|
31
|
+
* 4. **Default written out**, on the declared side where the live side has
|
|
32
|
+
* nothing: the author wrote the value Grafana assumes, which the
|
|
33
|
+
* translation leaves out.
|
|
34
|
+
*
|
|
35
|
+
* Rules 3 and 4 are gated on `counterpart === "absent"`, so a value the
|
|
36
|
+
* author did declare is always compared, and a change away from it is drift.
|
|
37
|
+
* (That relies on core walking a panel's props when it lists the declared
|
|
38
|
+
* paths, which #2946 fixed in `deepPathSet`.)
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
import type { DeepArrayElement, DeepNode, DeepNormalizationHooks } from "@intentius/chant/deep-observation";
|
|
42
|
+
import { DASHBOARD_TYPE } from "./dashboard";
|
|
43
|
+
import { DATASOURCE_TYPE, EXTERNAL_DATASOURCE_TYPE } from "./datasource";
|
|
44
|
+
import { FOLDER_TYPE } from "./folder";
|
|
45
|
+
import { registeredQueries } from "./query";
|
|
46
|
+
import { DASHBOARD_SCHEMA_VERSION } from "./schema/dashboard.gen";
|
|
47
|
+
import { BOOKKEEPING_KEYS, LINK_DEFAULTS, deepEqual, isBuiltinAnnotation } from "./import/normalize";
|
|
48
|
+
import { DATASOURCE_API_DEFAULTS } from "./import/live-export";
|
|
49
|
+
|
|
50
|
+
type Json = Record<string, unknown>;
|
|
51
|
+
|
|
52
|
+
/** Where a node sits in a dashboard tree, from its index-erased pattern. */
|
|
53
|
+
type Level = "dashboard" | "panel" | "target" | "variable" | "link" | "annotation";
|
|
54
|
+
|
|
55
|
+
const SEGMENT = "([^.\\[\\]]+)";
|
|
56
|
+
const PANEL = "panels\\[\\](?:\\.panels\\[\\])?";
|
|
57
|
+
const LEVELS: ReadonlyArray<[Level, RegExp]> = [
|
|
58
|
+
["dashboard", new RegExp(`^${SEGMENT}$`)],
|
|
59
|
+
["panel", new RegExp(`^${PANEL}\\.${SEGMENT}$`)],
|
|
60
|
+
["target", new RegExp(`^${PANEL}\\.targets\\[\\]\\.${SEGMENT}$`)],
|
|
61
|
+
["variable", new RegExp(`^variables\\[\\]\\.${SEGMENT}$`)],
|
|
62
|
+
["link", new RegExp(`^(?:${PANEL}\\.)?links\\[\\]\\.${SEGMENT}$`)],
|
|
63
|
+
["annotation", new RegExp(`^annotations\\[\\]\\.${SEGMENT}$`)],
|
|
64
|
+
];
|
|
65
|
+
|
|
66
|
+
function levelOf(pattern: string): { level: Level; key: string } | undefined {
|
|
67
|
+
for (const [level, re] of LEVELS) {
|
|
68
|
+
const m = re.exec(pattern);
|
|
69
|
+
if (m) return { level, key: m[1] };
|
|
70
|
+
}
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Defaults in the props vocabulary: a key an author may write at this value,
|
|
76
|
+
* and the translation leaves out because Grafana assumes it. The dashboard
|
|
77
|
+
* and panel entries mirror `DASHBOARD_DEFAULTS` and `PANEL_DEFAULTS` in
|
|
78
|
+
* ./import/normalize.ts, with `graphTooltip` spelled as `Dashboard` takes it.
|
|
79
|
+
*/
|
|
80
|
+
export const PROP_DEFAULTS: Readonly<Record<Level, Readonly<Json>>> = {
|
|
81
|
+
dashboard: {
|
|
82
|
+
editable: true,
|
|
83
|
+
fiscalYearStartMonth: 0,
|
|
84
|
+
graphTooltip: "default",
|
|
85
|
+
links: [],
|
|
86
|
+
tags: [],
|
|
87
|
+
time: { from: "now-6h", to: "now" },
|
|
88
|
+
timepicker: {},
|
|
89
|
+
timezone: "",
|
|
90
|
+
weekStart: "",
|
|
91
|
+
refresh: "",
|
|
92
|
+
liveNow: false,
|
|
93
|
+
description: "",
|
|
94
|
+
schemaVersion: DASHBOARD_SCHEMA_VERSION,
|
|
95
|
+
},
|
|
96
|
+
panel: {
|
|
97
|
+
title: "",
|
|
98
|
+
description: "",
|
|
99
|
+
options: {},
|
|
100
|
+
targets: [],
|
|
101
|
+
transformations: [],
|
|
102
|
+
links: [],
|
|
103
|
+
transparent: false,
|
|
104
|
+
hideTimeOverride: false,
|
|
105
|
+
repeatDirection: "h",
|
|
106
|
+
// A row's.
|
|
107
|
+
collapsed: false,
|
|
108
|
+
panels: [],
|
|
109
|
+
},
|
|
110
|
+
target: {},
|
|
111
|
+
variable: {
|
|
112
|
+
label: "",
|
|
113
|
+
description: "",
|
|
114
|
+
hide: "label",
|
|
115
|
+
skipUrlSync: false,
|
|
116
|
+
multi: false,
|
|
117
|
+
includeAll: false,
|
|
118
|
+
allValue: "",
|
|
119
|
+
regex: "",
|
|
120
|
+
sort: 0,
|
|
121
|
+
refresh: "onLoad",
|
|
122
|
+
auto: false,
|
|
123
|
+
autoCount: 30,
|
|
124
|
+
autoMin: "10s",
|
|
125
|
+
},
|
|
126
|
+
link: LINK_DEFAULTS,
|
|
127
|
+
// Grafana 13.2 drops `hide: false` from an annotation it stores.
|
|
128
|
+
annotation: { hide: false },
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
/** What the build writes into an annotation that leaves them out (annotations.ts `annotationJson`). */
|
|
132
|
+
const ANNOTATION_BUILD_DEFAULTS: Readonly<Json> = { enable: true, iconColor: "red" };
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Keys the build fills in when a declaration leaves them out, by level:
|
|
136
|
+
* the dashboard's uid (from its export name) and schema version, a panel's
|
|
137
|
+
* id, grid position and datasource (from its queries), a query's refId.
|
|
138
|
+
* Grafana keeps what the build wrote, so undeclared, they read back as the
|
|
139
|
+
* build's choice rather than as anybody's edit.
|
|
140
|
+
*
|
|
141
|
+
* `timezone` is here as a value, not a key: chant writes `browser` for a
|
|
142
|
+
* dashboard that names none, where Grafana's own default is `""`.
|
|
143
|
+
*/
|
|
144
|
+
export const BUILD_DERIVED: Readonly<Record<Level, ReadonlySet<string>>> = {
|
|
145
|
+
dashboard: new Set(["uid", "schemaVersion"]),
|
|
146
|
+
panel: new Set(["id", "gridPos", "datasource", "pluginVersion"]),
|
|
147
|
+
target: new Set(["refId", "datasource"]),
|
|
148
|
+
// A query variable's selection is whatever the viewer last saved; the build writes one only when it is declared.
|
|
149
|
+
variable: new Set(["current", "datasource"]),
|
|
150
|
+
link: new Set(),
|
|
151
|
+
annotation: new Set(),
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
/** Defaults the build merges into a query from its class (`queryType: "traceql"`, `filters: []`): any key some class defaults, at that value. */
|
|
155
|
+
function queryDefault(key: string, value: unknown): boolean {
|
|
156
|
+
for (const def of registeredQueries()) {
|
|
157
|
+
const defaults = (def as { defaults?: Json }).defaults;
|
|
158
|
+
if (defaults && key in defaults && deepEqual(defaults[key], value)) return true;
|
|
159
|
+
}
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/** `[]` or a plain `{}`. Not a declarable, whose own keys are not enumerable. */
|
|
164
|
+
function isEmptyContainer(value: unknown): boolean {
|
|
165
|
+
if (Array.isArray(value)) return value.length === 0;
|
|
166
|
+
if (typeof value !== "object" || value === null) return false;
|
|
167
|
+
const proto = Object.getPrototypeOf(value) as unknown;
|
|
168
|
+
return (proto === Object.prototype || proto === null) && Object.keys(value).length === 0;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function isEmptyFieldConfig(value: unknown): boolean {
|
|
172
|
+
return isEmptyContainer(value) || deepEqual(value, { defaults: {}, overrides: [] });
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/** Any node at or under a `datasource` key: a reference, whichever form (ref, variable, entity) it takes. */
|
|
176
|
+
function underDatasource(pattern: string): boolean {
|
|
177
|
+
return /(^|\.)datasource(\.|$)/.test(pattern);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function isDatasourceType(entityType: string): boolean {
|
|
181
|
+
return entityType === DATASOURCE_TYPE || entityType === EXTERNAL_DATASOURCE_TYPE;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function pruneDatasource(node: DeepNode): boolean {
|
|
185
|
+
// 1. The organisation is where it lives, not a property of it; the version is Grafana's save counter.
|
|
186
|
+
if (node.pattern === "orgId" || node.pattern === "version") return true;
|
|
187
|
+
// 2.
|
|
188
|
+
if (node.value === null || isEmptyContainer(node.value)) return true;
|
|
189
|
+
if (node.counterpart !== "absent") return false;
|
|
190
|
+
if (node.side === "live") {
|
|
191
|
+
// 3. The uid comes from the name when not declared; `editable` is `!readOnly`, true for one created in the UI or API.
|
|
192
|
+
return node.pattern === "uid" || node.pattern === "editable";
|
|
193
|
+
}
|
|
194
|
+
// 4.
|
|
195
|
+
if (node.pattern === "editable") return node.value === false;
|
|
196
|
+
return node.pattern in DATASOURCE_API_DEFAULTS && deepEqual(DATASOURCE_API_DEFAULTS[node.pattern], node.value);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function pruneDashboard(node: DeepNode): boolean {
|
|
200
|
+
const at = levelOf(node.pattern);
|
|
201
|
+
|
|
202
|
+
// 1. Bookkeeping and Grafana's own additions, whatever either side says.
|
|
203
|
+
if (at?.level === "dashboard" && BOOKKEEPING_KEYS.includes(at.key)) return true;
|
|
204
|
+
if (/^annotations(\.list)?\[\]$/.test(node.pattern) && isBuiltinAnnotation(node.value)) return true;
|
|
205
|
+
if (at?.level === "panel" && (at.key === "options" || at.key === "fieldConfig") && isEmptyFieldConfig(node.value)) return true;
|
|
206
|
+
|
|
207
|
+
// 2. Empty is absent, on both sides whatever the other has. Grafana drops
|
|
208
|
+
// every `null` when it stores a dashboard through /apis, and an empty list
|
|
209
|
+
// or object means what leaving the key out means. Not gated on the
|
|
210
|
+
// counterpart, which is matched by pattern: a threshold's first step has
|
|
211
|
+
// `value: null` where the others have a number, and one panel's
|
|
212
|
+
// `overrides: []` sits beside another's list of overrides.
|
|
213
|
+
if (node.value === null || isEmptyContainer(node.value)) return true;
|
|
214
|
+
if (node.counterpart !== "absent") return false;
|
|
215
|
+
|
|
216
|
+
if (node.side === "live") {
|
|
217
|
+
// 3. Build-derived.
|
|
218
|
+
if (underDatasource(node.pattern)) return true;
|
|
219
|
+
if (/^panels\[\](?:\.panels\[\])?\.gridPos\./.test(node.pattern)) return true;
|
|
220
|
+
if (!at) return false;
|
|
221
|
+
if (BUILD_DERIVED[at.level].has(at.key)) return true;
|
|
222
|
+
if (at.level === "dashboard" && at.key === "timezone" && node.value === "browser") return true;
|
|
223
|
+
if (at.level === "target" && queryDefault(at.key, node.value)) return true;
|
|
224
|
+
if (at.level === "link" && at.key in LINK_DEFAULTS && deepEqual(LINK_DEFAULTS[at.key], node.value)) return true;
|
|
225
|
+
if (at.level === "annotation" && at.key in ANNOTATION_BUILD_DEFAULTS && deepEqual(ANNOTATION_BUILD_DEFAULTS[at.key], node.value)) return true;
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// 4. A default written out.
|
|
230
|
+
if (!at) return false;
|
|
231
|
+
const defaults = PROP_DEFAULTS[at.level];
|
|
232
|
+
return at.key in defaults && deepEqual(defaults[at.key], node.value);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/** A folder's uid comes from its path when it is not declared. */
|
|
236
|
+
function pruneFolder(node: DeepNode): boolean {
|
|
237
|
+
return node.side === "live" && node.counterpart === "absent" && node.pattern === "uid";
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
export const grafanaDeepNormalizationHooks: DeepNormalizationHooks = {
|
|
241
|
+
prune(node: DeepNode): boolean {
|
|
242
|
+
if (node.entityType === DASHBOARD_TYPE) return pruneDashboard(node);
|
|
243
|
+
if (node.entityType === FOLDER_TYPE) return pruneFolder(node);
|
|
244
|
+
if (isDatasourceType(node.entityType)) return pruneDatasource(node);
|
|
245
|
+
return false;
|
|
246
|
+
},
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* A datasource's secrets are compared by key, never by value: Grafana
|
|
250
|
+
* returns only which ones are set, the reader writes those as
|
|
251
|
+
* `[REDACTED]`, and the declared values (`$__env{...}` references, or
|
|
252
|
+
* worse) are masked the same way.
|
|
253
|
+
*/
|
|
254
|
+
mask(node: DeepNode): boolean {
|
|
255
|
+
return isDatasourceType(node.entityType) && /^secureJsonData\./.test(node.pattern);
|
|
256
|
+
},
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Dashboard tags are a set. Nothing else is reordered: panel order is
|
|
260
|
+
* layout order, and variable and link order is the order Grafana shows
|
|
261
|
+
* them in.
|
|
262
|
+
*/
|
|
263
|
+
orderKey(element: DeepArrayElement): string | undefined {
|
|
264
|
+
if (element.entityType === DASHBOARD_TYPE && element.pattern === "tags" && typeof element.element === "string") return element.element;
|
|
265
|
+
return undefined;
|
|
266
|
+
},
|
|
267
|
+
};
|