@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/build.test.ts
CHANGED
|
@@ -1,23 +1,29 @@
|
|
|
1
1
|
import { describe, expect, test } from "vitest";
|
|
2
|
-
import { Datasource } from "./datasource";
|
|
3
|
-
import { Dashboard } from "./dashboard";
|
|
2
|
+
import { Datasource, DatasourceProvisioning, ExternalDatasource } from "./datasource";
|
|
3
|
+
import { Dashboard, DashboardProvider } from "./dashboard";
|
|
4
|
+
import { Folder } from "./folder";
|
|
5
|
+
import { load } from "js-yaml";
|
|
4
6
|
import { Row, StatPanel, TextPanel, TimeSeriesPanel, TablePanel, definePanel } from "./panels";
|
|
5
7
|
import { PromQuery, TempoQuery, LokiQuery, defineQuery } from "./query";
|
|
6
8
|
import {
|
|
9
|
+
AdhocVariable,
|
|
7
10
|
CustomVariable,
|
|
8
11
|
ConstantVariable,
|
|
9
12
|
DatasourceVariable,
|
|
13
|
+
GroupByVariable,
|
|
10
14
|
IntervalVariable,
|
|
11
15
|
QueryVariable,
|
|
16
|
+
SwitchVariable,
|
|
12
17
|
TextboxVariable,
|
|
13
18
|
} from "./variables";
|
|
14
|
-
import { panelsJson, renderDashboard, variableModel, dashboardJson, grafanaFiles, type PanelJson } from "./build";
|
|
19
|
+
import { panelsJson, renderDashboard, variableModel, dashboardJson, grafanaFiles, buildGrafana, customVariableOptions, type PanelJson } from "./build";
|
|
15
20
|
|
|
16
21
|
/** The panels array, read as plain panels (the tests below build no rows unless they say so). */
|
|
17
22
|
function panelsOnly(items: Parameters<typeof panelsJson>[0]): PanelJson[] {
|
|
18
23
|
return panelsJson(items) as PanelJson[];
|
|
19
24
|
}
|
|
20
25
|
import { validateDashboardSchema } from "./schema-validate";
|
|
26
|
+
import { checkGrid } from "./validate-output";
|
|
21
27
|
|
|
22
28
|
const prometheus = new Datasource({ name: "Prometheus", type: "prometheus" });
|
|
23
29
|
const tempo = new Datasource({ name: "Tempo", type: "tempo" });
|
|
@@ -77,6 +83,138 @@ describe("layout", () => {
|
|
|
77
83
|
expect((panels[1] as unknown as { panels: unknown[] }).panels).toEqual([]);
|
|
78
84
|
});
|
|
79
85
|
|
|
86
|
+
test("a row with a y keeps that line, even over an empty band or on a line a panel takes (#2992)", () => {
|
|
87
|
+
const panels = panelsJson([
|
|
88
|
+
new StatPanel({ title: "a", gridPos: { x: 0, y: 0, w: 24, h: 4 } }),
|
|
89
|
+
new Row({ title: "late", gridPos: { y: 6 }, panels: [new StatPanel({ title: "b", gridPos: { x: 0, y: 7, w: 24, h: 4 } })] }),
|
|
90
|
+
new Row({ title: "auto", panels: [new StatPanel({ title: "c" })] }),
|
|
91
|
+
new Row({ title: "early", gridPos: { y: 8 } }),
|
|
92
|
+
]);
|
|
93
|
+
expect(panels.map((p) => [p.title, p.gridPos])).toEqual([
|
|
94
|
+
["a", { h: 4, w: 24, x: 0, y: 0 }],
|
|
95
|
+
["late", { h: 1, w: 24, x: 0, y: 6 }],
|
|
96
|
+
["b", { h: 4, w: 24, x: 0, y: 7 }],
|
|
97
|
+
// An auto-placed row skips the line the "early" row reserved.
|
|
98
|
+
["auto", { h: 1, w: 24, x: 0, y: 11 }],
|
|
99
|
+
["c", { h: 4, w: 6, x: 0, y: 12 }],
|
|
100
|
+
["early", { h: 1, w: 24, x: 0, y: 8 }],
|
|
101
|
+
]);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test("an auto-placed panel flows around an explicit one declared before it (#2941)", () => {
|
|
105
|
+
const panels = panelsJson([
|
|
106
|
+
new TimeSeriesPanel({ title: "a", gridPos: { x: 0, y: 0, w: 12 } }),
|
|
107
|
+
new TimeSeriesPanel({ title: "b", gridPos: { w: 12 } }),
|
|
108
|
+
]);
|
|
109
|
+
expect(panels.map((p) => p.gridPos)).toEqual([
|
|
110
|
+
{ h: 8, w: 12, x: 0, y: 0 },
|
|
111
|
+
{ h: 8, w: 12, x: 12, y: 0 },
|
|
112
|
+
]);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
test("an explicit panel reserves its cells even when declared after auto-placed ones", () => {
|
|
116
|
+
const panels = panelsJson([
|
|
117
|
+
new StatPanel({ title: "s1" }),
|
|
118
|
+
new StatPanel({ title: "s2" }),
|
|
119
|
+
new StatPanel({ title: "s3" }),
|
|
120
|
+
new StatPanel({ title: "s4" }),
|
|
121
|
+
new StatPanel({ title: "pinned", gridPos: { x: 6, y: 0, w: 6, h: 4 } }),
|
|
122
|
+
new TextPanel({ title: "wide" }),
|
|
123
|
+
]);
|
|
124
|
+
expect(panels.map((p) => [p.title, p.gridPos])).toEqual([
|
|
125
|
+
["s1", { h: 4, w: 6, x: 0, y: 0 }],
|
|
126
|
+
["s2", { h: 4, w: 6, x: 12, y: 0 }],
|
|
127
|
+
["s3", { h: 4, w: 6, x: 18, y: 0 }],
|
|
128
|
+
["s4", { h: 4, w: 6, x: 0, y: 4 }],
|
|
129
|
+
["pinned", { h: 4, w: 6, x: 6, y: 0 }],
|
|
130
|
+
["wide", { h: 3, w: 24, x: 0, y: 8 }],
|
|
131
|
+
]);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
test("a line blocked by an explicit panel is skipped", () => {
|
|
135
|
+
const panels = panelsJson([
|
|
136
|
+
new StatPanel({ title: "band", gridPos: { x: 0, y: 0, w: 24, h: 2 } }),
|
|
137
|
+
new StatPanel({ title: "hole", gridPos: { x: 0, y: 6, w: 6, h: 2 } }),
|
|
138
|
+
new StatPanel({ title: "s1" }),
|
|
139
|
+
new TextPanel({ title: "wide" }),
|
|
140
|
+
]);
|
|
141
|
+
expect(panels.map((p) => [p.title, p.gridPos])).toEqual([
|
|
142
|
+
["band", { h: 2, w: 24, x: 0, y: 0 }],
|
|
143
|
+
["hole", { h: 2, w: 6, x: 0, y: 6 }],
|
|
144
|
+
["s1", { h: 4, w: 6, x: 0, y: 2 }],
|
|
145
|
+
["wide", { h: 3, w: 24, x: 0, y: 8 }],
|
|
146
|
+
]);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
test("a partial gridPos is honoured: x only keeps its column, y only its line", () => {
|
|
150
|
+
const panels = panelsJson([
|
|
151
|
+
new StatPanel({ title: "right", gridPos: { x: 18 } }),
|
|
152
|
+
new StatPanel({ title: "left", gridPos: { x: 0 } }),
|
|
153
|
+
new StatPanel({ title: "next" }),
|
|
154
|
+
new StatPanel({ title: "low", gridPos: { y: 20, w: 12 } }),
|
|
155
|
+
new StatPanel({ title: "low2", gridPos: { y: 20, w: 12 } }),
|
|
156
|
+
new StatPanel({ title: "low3", gridPos: { y: 20, w: 12 } }),
|
|
157
|
+
]);
|
|
158
|
+
expect(panels.map((p) => [p.title, p.gridPos])).toEqual([
|
|
159
|
+
["right", { h: 4, w: 6, x: 18, y: 0 }],
|
|
160
|
+
["left", { h: 4, w: 6, x: 0, y: 4 }],
|
|
161
|
+
["next", { h: 4, w: 6, x: 6, y: 4 }],
|
|
162
|
+
["low", { h: 4, w: 12, x: 0, y: 20 }],
|
|
163
|
+
["low2", { h: 4, w: 12, x: 12, y: 20 }],
|
|
164
|
+
["low3", { h: 4, w: 12, x: 0, y: 24 }],
|
|
165
|
+
]);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
test("a full-width row header skips lines taken by explicit panels", () => {
|
|
169
|
+
const panels = panelsJson([
|
|
170
|
+
new TimeSeriesPanel({ title: "top" }),
|
|
171
|
+
new Row({
|
|
172
|
+
title: "open",
|
|
173
|
+
panels: [new StatPanel({ title: "pinned", gridPos: { x: 0, y: 8, w: 24, h: 2 } }), new StatPanel({ title: "a" })],
|
|
174
|
+
}),
|
|
175
|
+
new Row({ title: "next" }),
|
|
176
|
+
]);
|
|
177
|
+
expect(panels.map((p) => [p.type, p.title, p.gridPos])).toEqual([
|
|
178
|
+
["timeseries", "top", { h: 8, w: 12, x: 0, y: 0 }],
|
|
179
|
+
["row", "open", { h: 1, w: 24, x: 0, y: 10 }],
|
|
180
|
+
["stat", "pinned", { h: 2, w: 24, x: 0, y: 8 }],
|
|
181
|
+
["stat", "a", { h: 4, w: 6, x: 0, y: 11 }],
|
|
182
|
+
["row", "next", { h: 1, w: 24, x: 0, y: 15 }],
|
|
183
|
+
]);
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
test("a collapsed row's panels flow around its own explicit panels and don't block the dashboard", () => {
|
|
187
|
+
const panels = panelsJson([
|
|
188
|
+
new Row({
|
|
189
|
+
title: "shut",
|
|
190
|
+
collapsed: true,
|
|
191
|
+
panels: [new StatPanel({ title: "pinned", gridPos: { x: 0, y: 1, w: 6, h: 4 } }), new StatPanel({ title: "a" })],
|
|
192
|
+
}),
|
|
193
|
+
new StatPanel({ title: "after" }),
|
|
194
|
+
]);
|
|
195
|
+
const shut = panels[0] as unknown as { panels: PanelJson[] };
|
|
196
|
+
expect(shut.panels.map((p) => [p.title, p.gridPos])).toEqual([
|
|
197
|
+
["pinned", { h: 4, w: 6, x: 0, y: 1 }],
|
|
198
|
+
["a", { h: 4, w: 6, x: 6, y: 1 }],
|
|
199
|
+
]);
|
|
200
|
+
expect(panels[1].gridPos).toEqual({ h: 4, w: 6, x: 0, y: 1 });
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
test("a mixed layout built by the dashboard passes GRAF105", () => {
|
|
204
|
+
const dash = new Dashboard({
|
|
205
|
+
title: "Mixed",
|
|
206
|
+
panels: [
|
|
207
|
+
new TimeSeriesPanel({ title: "a", gridPos: { x: 0, y: 0, w: 12 } }),
|
|
208
|
+
new TimeSeriesPanel({ title: "b", gridPos: { w: 12 } }),
|
|
209
|
+
new StatPanel({ title: "c", gridPos: { x: 6 } }),
|
|
210
|
+
new StatPanel({ title: "d", gridPos: { x: 12, y: 8, w: 12, h: 4 } }),
|
|
211
|
+
new StatPanel({ title: "e" }),
|
|
212
|
+
new Row({ title: "r", panels: [new StatPanel({ title: "f", gridPos: { x: 18, y: 12 } }), new StatPanel({ title: "g" })] }),
|
|
213
|
+
],
|
|
214
|
+
});
|
|
215
|
+
expect(checkGrid({ dashboards: [{ json: JSON.parse(dashboardJson(dash)) }], datasources: [] })).toEqual([]);
|
|
216
|
+
});
|
|
217
|
+
|
|
80
218
|
test("auto ids skip ids set explicitly", () => {
|
|
81
219
|
const panels = panelsJson([new StatPanel(), new StatPanel({ id: 1 }), new StatPanel()]);
|
|
82
220
|
expect(panels.map((p) => p.id)).toEqual([2, 1, 3]);
|
|
@@ -102,6 +240,17 @@ describe("datasources and targets", () => {
|
|
|
102
240
|
]);
|
|
103
241
|
});
|
|
104
242
|
|
|
243
|
+
test("a panel declared Mixed stays Mixed, and a query naming no datasource is not sent to Mixed (#2992)", () => {
|
|
244
|
+
const mixed = { type: "datasource", uid: "-- Mixed --" };
|
|
245
|
+
const [bare, panel] = panelsOnly([
|
|
246
|
+
new TextPanel({ datasource: mixed }),
|
|
247
|
+
new StatPanel({ datasource: mixed, targets: [new PromQuery({ expr: "up", datasource: prometheus }), new PromQuery({ expr: "down" })] }),
|
|
248
|
+
]);
|
|
249
|
+
expect(bare.datasource).toEqual(mixed);
|
|
250
|
+
expect(panel.datasource).toEqual(mixed);
|
|
251
|
+
expect(panel.targets!.map((t) => (t as { datasource?: unknown }).datasource)).toEqual([{ type: "prometheus", uid: "prometheus" }, undefined]);
|
|
252
|
+
});
|
|
253
|
+
|
|
105
254
|
test("a panel takes its queries' shared datasource, and a row passes its own down", () => {
|
|
106
255
|
const [shared] = panelsOnly([new StatPanel({ targets: [new PromQuery({ expr: "up", datasource: prometheus })] })]);
|
|
107
256
|
expect(shared.datasource).toEqual({ type: "prometheus", uid: "prometheus" });
|
|
@@ -158,6 +307,98 @@ describe("variables", () => {
|
|
|
158
307
|
expect(variableModel(new TextboxVariable({ name: "q" }))).toMatchObject({ type: "textbox", query: "" });
|
|
159
308
|
});
|
|
160
309
|
|
|
310
|
+
test("an object query is written as it is, its text as the definition", () => {
|
|
311
|
+
const query = { qryType: 1 as const, query: "label_values(up, job)", refId: "PrometheusVariableQueryEditor-VariableQuery" };
|
|
312
|
+
expect(variableModel(new QueryVariable({ name: "job", datasource: prometheus, query }))).toMatchObject({ query, definition: "label_values(up, job)" });
|
|
313
|
+
expect(variableModel(new QueryVariable({ name: "ns", datasource: prometheus, query: { namespace: "AWS/EC2" }, definition: "Namespaces" }))).toMatchObject({
|
|
314
|
+
query: { namespace: "AWS/EC2" },
|
|
315
|
+
definition: "Namespaces",
|
|
316
|
+
});
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
test("ad hoc, group by and switch variables as Grafana writes them", () => {
|
|
320
|
+
const ds = new DatasourceVariable({ name: "ds", pluginType: "prometheus" });
|
|
321
|
+
expect(variableModel(new AdhocVariable({ name: "f", datasource: ds, filters: [{ key: "ns", operator: "=", value: "shop" }] }))).toEqual({
|
|
322
|
+
type: "adhoc",
|
|
323
|
+
name: "f",
|
|
324
|
+
datasource: { type: "prometheus", uid: "${ds}" },
|
|
325
|
+
filters: [{ key: "ns", operator: "=", value: "shop" }],
|
|
326
|
+
baseFilters: [],
|
|
327
|
+
});
|
|
328
|
+
expect(variableModel(new GroupByVariable({ name: "by", datasource: prometheus, options: ["pod", { text: "Node", value: "node" }], defaultValue: ["pod"] }))).toEqual({
|
|
329
|
+
type: "groupby",
|
|
330
|
+
name: "by",
|
|
331
|
+
datasource: { type: "prometheus", uid: prometheus.uid },
|
|
332
|
+
options: [
|
|
333
|
+
{ text: "pod", value: "pod" },
|
|
334
|
+
{ text: "Node", value: "node" },
|
|
335
|
+
],
|
|
336
|
+
current: { text: ["pod"], value: ["pod"] },
|
|
337
|
+
defaultValue: { text: ["pod"], value: ["pod"] },
|
|
338
|
+
});
|
|
339
|
+
expect(variableModel(new SwitchVariable({ name: "on" }))).toEqual({
|
|
340
|
+
type: "switch",
|
|
341
|
+
name: "on",
|
|
342
|
+
current: { text: "false", value: "false" },
|
|
343
|
+
options: [
|
|
344
|
+
{ text: "true", value: "true" },
|
|
345
|
+
{ text: "false", value: "false" },
|
|
346
|
+
],
|
|
347
|
+
});
|
|
348
|
+
expect(variableModel(new SwitchVariable({ name: "q", enabled: true, enabledValue: "0.99", disabledValue: "0.5" }))).toMatchObject({
|
|
349
|
+
current: { text: "0.99", value: "0.99" },
|
|
350
|
+
options: [
|
|
351
|
+
{ text: "0.99", value: "0.99" },
|
|
352
|
+
{ text: "0.5", value: "0.5" },
|
|
353
|
+
],
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
test("a custom value in Grafana's `text : value` syntax shows the text and sets the value (#2944)", () => {
|
|
358
|
+
const v = variableModel(new CustomVariable({ name: "env", values: ["Production : prod", "Staging : stg", "dev"] }));
|
|
359
|
+
expect(v).toMatchObject({
|
|
360
|
+
query: "Production : prod,Staging : stg,dev",
|
|
361
|
+
current: { text: "Production", value: "prod" },
|
|
362
|
+
options: [
|
|
363
|
+
{ selected: true, text: "Production", value: "prod" },
|
|
364
|
+
{ selected: false, text: "Staging", value: "stg" },
|
|
365
|
+
{ selected: false, text: "dev", value: "dev" },
|
|
366
|
+
],
|
|
367
|
+
});
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
test("a custom value's selected option follows current by value, and multi-value current selects several", () => {
|
|
371
|
+
const v = variableModel(
|
|
372
|
+
new CustomVariable({ name: "env", multi: true, values: ["Production : prod", "Staging : stg"], current: { text: ["Staging"], value: ["stg"] } }),
|
|
373
|
+
);
|
|
374
|
+
expect((v as { options: Array<{ selected: boolean }> }).options.map((o) => o.selected)).toEqual([false, true]);
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
test("a comma already escaped as \\, is not escaped again (#2944)", () => {
|
|
378
|
+
const v = variableModel(new CustomVariable({ name: "pair", values: ["a\\,b", "c,d", "Label, with comma : x\\,y"] }));
|
|
379
|
+
expect(v).toMatchObject({
|
|
380
|
+
query: "a\\,b,c\\,d,Label\\, with comma : x\\,y",
|
|
381
|
+
options: [
|
|
382
|
+
{ text: "a,b", value: "a,b" },
|
|
383
|
+
{ text: "c,d", value: "c,d" },
|
|
384
|
+
{ text: "Label, with comma", value: "x,y" },
|
|
385
|
+
],
|
|
386
|
+
});
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
test("customVariableOptions parses a query the way Grafana does", () => {
|
|
390
|
+
expect(customVariableOptions("a : 1, b,c\\,d , ,x:y, k : v : w")).toEqual([
|
|
391
|
+
{ text: "a", value: "1" },
|
|
392
|
+
{ text: "b", value: "b" },
|
|
393
|
+
{ text: "c,d", value: "c,d" },
|
|
394
|
+
{ text: "", value: "" },
|
|
395
|
+
// No spaces around the colon: one plain value.
|
|
396
|
+
{ text: "x:y", value: "x:y" },
|
|
397
|
+
// Grafana's first group is greedy: the last ` : ` splits.
|
|
398
|
+
{ text: "k : v", value: "w" },
|
|
399
|
+
]);
|
|
400
|
+
});
|
|
401
|
+
|
|
161
402
|
test("a dashboard with every variable kind matches the dashboard schema", () => {
|
|
162
403
|
const dash = new Dashboard({
|
|
163
404
|
title: "Vars",
|
|
@@ -168,6 +409,10 @@ describe("variables", () => {
|
|
|
168
409
|
new DatasourceVariable({ name: "ds", pluginType: "prometheus" }),
|
|
169
410
|
new ConstantVariable({ name: "cluster", value: "x" }),
|
|
170
411
|
new TextboxVariable({ name: "q", value: "y" }),
|
|
412
|
+
new QueryVariable({ name: "pods", datasource: prometheus, query: { qryType: 1, query: "label_values(kube_pod_info, pod)" } }),
|
|
413
|
+
new AdhocVariable({ name: "f", datasource: prometheus, baseFilters: [{ key: "cluster", operator: "=", value: "prod" }], defaultKeys: [{ text: "pod" }] }),
|
|
414
|
+
new GroupByVariable({ name: "by", datasource: prometheus, options: ["pod"] }),
|
|
415
|
+
new SwitchVariable({ name: "on", enabled: true }),
|
|
171
416
|
],
|
|
172
417
|
});
|
|
173
418
|
expect(validateDashboardSchema(renderDashboard(dash) as unknown as Record<string, unknown>)).toEqual([]);
|
|
@@ -176,17 +421,17 @@ describe("variables", () => {
|
|
|
176
421
|
|
|
177
422
|
describe("extension points", () => {
|
|
178
423
|
test("definePanel and defineQuery produce classes that render and lay out like built-ins", () => {
|
|
179
|
-
const
|
|
180
|
-
const
|
|
181
|
-
const
|
|
424
|
+
const ClockPanel = definePanel<{ mode?: "time" | "countdown" }>()({ type: "grafana-clock-panel", className: "ClockPanel", defaultSize: { w: 8, h: 8 } });
|
|
425
|
+
const OpenSearchQuery = defineQuery<{ query: string; refId?: string }>()({ datasourceType: "grafana-opensearch-datasource", className: "OpenSearchQuery" });
|
|
426
|
+
const os = new Datasource({ name: "Logs OS", type: "grafana-opensearch-datasource" });
|
|
182
427
|
const json = renderDashboard(
|
|
183
|
-
new Dashboard({ title: "Custom", panels: [new
|
|
428
|
+
new Dashboard({ title: "Custom", panels: [new ClockPanel({ options: { mode: "countdown" }, datasource: os, targets: [new OpenSearchQuery({ query: "*" })] })] }),
|
|
184
429
|
);
|
|
185
430
|
expect(json.panels![0]).toMatchObject({
|
|
186
|
-
type: "
|
|
431
|
+
type: "grafana-clock-panel",
|
|
187
432
|
gridPos: { w: 8, h: 8, x: 0, y: 0 },
|
|
188
|
-
options: {
|
|
189
|
-
datasource: { type: "
|
|
433
|
+
options: { mode: "countdown" },
|
|
434
|
+
datasource: { type: "grafana-opensearch-datasource", uid: "logs-os" },
|
|
190
435
|
targets: [{ refId: "A", query: "*" }],
|
|
191
436
|
});
|
|
192
437
|
expect(validateDashboardSchema(json as unknown as Record<string, unknown>)).toEqual([]);
|
|
@@ -208,3 +453,99 @@ describe("extension points", () => {
|
|
|
208
453
|
]);
|
|
209
454
|
});
|
|
210
455
|
});
|
|
456
|
+
|
|
457
|
+
describe("folders (#2944)", () => {
|
|
458
|
+
test("a nested folder is written as nested directories under dashboards/", () => {
|
|
459
|
+
const built = buildGrafana([new Dashboard({ title: "Pods", uid: "pods", folder: "Platform/Kubernetes" })]);
|
|
460
|
+
expect(built.dashboards[0].file).toBe("dashboards/Platform/Kubernetes/pods.json");
|
|
461
|
+
expect(built.index.dashboards[0].folder).toBe("Platform/Kubernetes");
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
test("blank levels, dot-led levels and backslashes can't leave dashboards/", () => {
|
|
465
|
+
const file = (folder: string) => buildGrafana([new Dashboard({ title: "D", uid: "d", folder })]).dashboards[0].file;
|
|
466
|
+
expect(file("/Platform//Kubernetes/")).toBe("dashboards/Platform/Kubernetes/d.json");
|
|
467
|
+
expect(file("../../etc")).toBe("dashboards/etc/d.json");
|
|
468
|
+
expect(file("a\\b")).toBe("dashboards/a-b/d.json");
|
|
469
|
+
expect(file(" / ")).toBe("dashboards/d.json");
|
|
470
|
+
});
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
describe("folder uids and nesting (#2953)", () => {
|
|
474
|
+
const platform = new Folder({ title: "Platform", uid: "plat" });
|
|
475
|
+
const k8s = new Folder({ title: "Kubernetes", parent: platform });
|
|
476
|
+
|
|
477
|
+
test("a Folder is written where its path is, and the index lists every level with its uid and parent", () => {
|
|
478
|
+
const built = buildGrafana(
|
|
479
|
+
new Map<string, never>([
|
|
480
|
+
["pods", new Dashboard({ title: "Pods", uid: "pods", folder: k8s }) as never],
|
|
481
|
+
["nodes", new Dashboard({ title: "Nodes", uid: "nodes", folder: "Platform/Kubernetes/Nodes" }) as never],
|
|
482
|
+
["spare", new Folder({ title: "Spare" }) as never],
|
|
483
|
+
]),
|
|
484
|
+
);
|
|
485
|
+
expect(built.dashboards.map((d) => [d.file, d.folder, d.folderUid])).toEqual([
|
|
486
|
+
["dashboards/Platform/Kubernetes/pods.json", "Platform/Kubernetes", "platform-kubernetes"],
|
|
487
|
+
["dashboards/Platform/Kubernetes/Nodes/nodes.json", "Platform/Kubernetes/Nodes", "platform-kubernetes-nodes"],
|
|
488
|
+
]);
|
|
489
|
+
expect(built.index.folders).toEqual([
|
|
490
|
+
{ uid: "plat", title: "Platform", path: "Platform" },
|
|
491
|
+
{ uid: "platform-kubernetes", title: "Kubernetes", parentUid: "plat", path: "Platform/Kubernetes" },
|
|
492
|
+
{ uid: "platform-kubernetes-nodes", title: "Nodes", parentUid: "platform-kubernetes", path: "Platform/Kubernetes/Nodes" },
|
|
493
|
+
{ uid: "spare", title: "Spare", path: "Spare" },
|
|
494
|
+
]);
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
test("a path and a Folder at the same path are one folder; the Folder's uid wins", () => {
|
|
498
|
+
const built = buildGrafana([new Dashboard({ title: "A", uid: "a", folder: "Platform" }), new Dashboard({ title: "B", uid: "b", folder: platform })]);
|
|
499
|
+
expect(built.dashboards.map((d) => d.folderUid)).toEqual(["plat", "plat"]);
|
|
500
|
+
expect(built.folders).toEqual([{ uid: "plat", title: "Platform", path: "Platform" }]);
|
|
501
|
+
});
|
|
502
|
+
|
|
503
|
+
test("a Folder title is one level, and two uids at one path are refused", () => {
|
|
504
|
+
expect(() => new Folder({ title: "Platform/Kubernetes" })).toThrow(/not one folder level/);
|
|
505
|
+
expect(() => buildGrafana([new Folder({ title: "X", uid: "one" }), new Folder({ title: "X", uid: "two" })])).toThrow(/declared with the uids "one" and "two"/);
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
test("a root-level Folder on a DashboardProvider is written as folder and folderUid; a nested one is refused", () => {
|
|
509
|
+
const built = buildGrafana([new DashboardProvider({ name: "ops", folder: platform, path: "/d" })]);
|
|
510
|
+
expect(built.providers[0]).toMatchObject({ folder: "Platform", folderUid: "plat", options: { foldersFromFilesStructure: false } });
|
|
511
|
+
expect(() => new DashboardProvider({ name: "ops", folder: k8s })).toThrow(/nested; Grafana creates a provider's folder at the root/);
|
|
512
|
+
});
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
describe("annotations (#2953)", () => {
|
|
516
|
+
test("an annotation is written with its datasource resolved and Grafana's defaults filled in", () => {
|
|
517
|
+
const json = renderDashboard(
|
|
518
|
+
new Dashboard({
|
|
519
|
+
title: "D",
|
|
520
|
+
annotations: [
|
|
521
|
+
{ name: "Deploys", datasource: prometheus, target: new PromQuery({ expr: "changes(up[5m]) > 0" }), titleFormat: "deploy" },
|
|
522
|
+
{ name: "Incidents", datasource: { type: "grafana", uid: "-- Grafana --" }, enable: false, iconColor: "blue", target: { type: "tags", tags: ["incident"], limit: 100, matchAny: false } },
|
|
523
|
+
],
|
|
524
|
+
}),
|
|
525
|
+
);
|
|
526
|
+
expect(json.annotations).toEqual({
|
|
527
|
+
list: [
|
|
528
|
+
{ datasource: { type: "prometheus", uid: "prometheus" }, enable: true, iconColor: "red", name: "Deploys", titleFormat: "deploy", target: expect.objectContaining({ refId: "Anno", expr: "changes(up[5m]) > 0" }) },
|
|
529
|
+
{ datasource: { type: "grafana", uid: "-- Grafana --" }, enable: false, iconColor: "blue", name: "Incidents", target: { type: "tags", tags: ["incident"], limit: 100, matchAny: false } },
|
|
530
|
+
],
|
|
531
|
+
});
|
|
532
|
+
expect(validateDashboardSchema(json as never).filter((p) => p.severity === "error")).toEqual([]);
|
|
533
|
+
expect(renderDashboard(new Dashboard({ title: "E" })).annotations).toEqual({ list: [] });
|
|
534
|
+
});
|
|
535
|
+
});
|
|
536
|
+
|
|
537
|
+
describe("datasource prune (#2953)", () => {
|
|
538
|
+
const files = (entities: unknown[]) => load(buildGrafana(entities as never).files["provisioning/datasources/chant.yaml"] ?? "null") as Record<string, unknown> | null;
|
|
539
|
+
|
|
540
|
+
test("the datasource file prunes by default, so a removed Datasource leaves Grafana", () => {
|
|
541
|
+
expect(files([prometheus])).toMatchObject({ apiVersion: 1, prune: true });
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
test("DatasourceProvisioning turns pruning off and lists datasources to delete", () => {
|
|
545
|
+
const out = files([prometheus, new DatasourceProvisioning({ prune: false, deleteDatasources: [{ name: "Old" }, { name: "Other", orgId: 2 }] })]);
|
|
546
|
+
expect(out).toEqual({ apiVersion: 1, deleteDatasources: [{ name: "Old" }, { name: "Other", orgId: 2 }], datasources: [expect.objectContaining({ name: "Prometheus" })] });
|
|
547
|
+
expect(files([new DatasourceProvisioning({ deleteDatasources: [{ name: "Old" }] })])).toEqual({ apiVersion: 1, prune: true, deleteDatasources: [{ name: "Old" }], datasources: [] });
|
|
548
|
+
expect(files([new ExternalDatasource({ type: "prometheus", uid: "p" })])).toBeNull();
|
|
549
|
+
expect(() => buildGrafana([new DatasourceProvisioning({}), new DatasourceProvisioning({})])).toThrow(/at most one DatasourceProvisioning/);
|
|
550
|
+
});
|
|
551
|
+
});
|