@intentius/chant-lexicon-grafana 0.97.0 → 0.99.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 +15 -5
- 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/api/apply.d.ts +156 -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 +61 -0
- package/dist/api/fake-grafana.d.ts.map +1 -0
- package/dist/api/folders.d.ts +110 -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 +30 -2
- 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/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 +7 -0
- 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 +16 -2
- package/dist/dashboard.d.ts.map +1 -1
- package/dist/datasource-refs.d.ts +95 -0
- package/dist/datasource-refs.d.ts.map +1 -0
- package/dist/datasource.d.ts +29 -0
- 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 +42 -0
- package/dist/deep-observe.d.ts.map +1 -0
- package/dist/describe-resources.d.ts +49 -0
- package/dist/describe-resources.d.ts.map +1 -0
- package/dist/detect.d.ts +28 -1
- 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/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 +83 -0
- package/dist/import/mappings.d.ts.map +1 -0
- package/dist/import/model.d.ts +98 -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 +110 -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 +35 -0
- package/dist/import/testdata/fixtures.d.ts.map +1 -0
- package/dist/import/v2.d.ts +72 -0
- package/dist/import/v2.d.ts.map +1 -0
- package/dist/index.d.ts +26 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/integrity.json +18 -10
- 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/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/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 +135 -0
- package/dist/okf/index.md +36 -2
- 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/GRAF108.md +11 -0
- package/dist/okf/rules/GRAF109.md +15 -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/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/BarChartPanel.md +9 -0
- package/dist/okf/types/BarGaugePanel.md +9 -0
- package/dist/okf/types/CanvasPanel.md +9 -0
- package/dist/okf/types/ClassicConditionsExpression.md +9 -0
- package/dist/okf/types/ContactPoint.md +14 -0
- package/dist/okf/types/Dashboard.md +1 -0
- package/dist/okf/types/Datasource.md +3 -2
- package/dist/okf/types/ExternalDatasource.md +15 -0
- package/dist/okf/types/FlameGraphPanel.md +9 -0
- package/dist/okf/types/GeomapPanel.md +9 -0
- package/dist/okf/types/HistogramPanel.md +9 -0
- package/dist/okf/types/MathExpression.md +9 -0
- package/dist/okf/types/MuteTiming.md +13 -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/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/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 +75 -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 +67 -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.d.ts +9 -8
- 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/graf107.ts +1 -1
- package/dist/rules/graf108.ts +17 -0
- package/dist/rules/graf109.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 +15 -8
- package/dist/rules/literal-secret.ts +60 -6
- 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/canvas.gen.d.ts +152 -0
- package/dist/schema/canvas.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/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/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 +12 -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 +22 -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 +30 -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-provisioning.md +3 -3
- package/dist/skills/chant-grafana.md +12 -6
- 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 +13 -7
- package/dist/spec/schemas.d.ts.map +1 -1
- 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 +49 -9
- package/dist/validate-output.d.ts.map +1 -1
- package/dist/validate.d.ts.map +1 -1
- package/dist/variables.d.ts +7 -2
- 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/api/apply.test.ts +238 -0
- package/src/api/apply.ts +384 -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 +186 -0
- package/src/api/folders.ts +265 -0
- package/src/api/library-panels.ts +101 -0
- package/src/build.test.ts +210 -5
- package/src/build.ts +180 -43
- package/src/catalog.ts +86 -2
- package/src/codegen/docs.ts +42 -9
- 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 +11 -0
- 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 +16 -2
- package/src/datasource-refs.test.ts +56 -0
- package/src/datasource-refs.ts +189 -0
- package/src/datasource.ts +52 -0
- package/src/deep-observe-hooks.ts +252 -0
- package/src/deep-observe.test.ts +265 -0
- package/src/deep-observe.ts +164 -0
- package/src/describe-resources.test.ts +255 -0
- package/src/describe-resources.ts +209 -0
- package/src/detect.ts +79 -2
- package/src/export-resources.test.ts +129 -0
- package/src/export-resources.ts +84 -0
- package/src/generated/lexicon-grafana.json +135 -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 +118 -0
- package/src/import/generator.test.ts +210 -0
- package/src/import/generator.ts +462 -0
- package/src/import/live-export.ts +264 -0
- package/src/import/mappings.ts +264 -0
- package/src/import/model.ts +110 -0
- package/src/import/normalize-alerting.ts +101 -0
- package/src/import/normalize.test.ts +117 -0
- package/src/import/normalize.ts +364 -0
- package/src/import/parser.test.ts +440 -0
- package/src/import/parser.ts +1236 -0
- package/src/import/report.ts +62 -0
- package/src/import/roundtrip.test.ts +468 -0
- package/src/import/testdata/fixtures.ts +129 -0
- package/src/import/v2.test.ts +292 -0
- package/src/import/v2.ts +803 -0
- package/src/import.e2e.test.ts +31 -84
- package/src/import.test.ts +9 -3
- package/src/index.ts +190 -5
- package/src/k8s.test.ts +98 -0
- package/src/k8s.ts +197 -0
- package/src/lint/audit-catalog.ts +60 -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/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/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 +15 -8
- package/src/lint/post-synth/index.ts +14 -0
- package/src/lint/post-synth/post-synth.test.ts +235 -11
- package/src/lint/rules/literal-secret.ts +60 -6
- package/src/lint/rules/rules.test.ts +27 -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 +175 -0
- package/src/op/activities/grafana-apply.test.ts +229 -0
- package/src/op/activities/grafana-apply.ts +171 -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 +103 -0
- package/src/panel-options.ts +66 -0
- package/src/panels.test.ts +51 -0
- package/src/panels.ts +148 -10
- package/src/pin.ts +57 -6
- package/src/plugin.test.ts +5 -2
- package/src/plugin.ts +66 -0
- package/src/promql-check.test.ts +108 -0
- package/src/promql-check.ts +189 -0
- package/src/query.ts +13 -8
- package/src/schema/barchart.gen.ts +221 -0
- package/src/schema/bargauge.gen.ts +111 -0
- package/src/schema/canvas.gen.ts +176 -0
- package/src/schema/dashboard.gen.ts +206 -22
- 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/heatmap.gen.ts +2 -1
- package/src/schema/histogram.gen.ts +151 -0
- package/src/schema/index.ts +12 -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 +27 -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 +141 -50
- 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 +17 -0
- package/src/skills/chant-grafana-alerting.md +49 -0
- package/src/skills/chant-grafana-provisioning.md +3 -3
- package/src/skills/chant-grafana.md +12 -6
- 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 +84 -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/barchart.jsonschema.json +419 -0
- package/src/spec/schemas/bargauge.jsonschema.json +224 -0
- package/src/spec/schemas/canvas.jsonschema.json +356 -0
- package/src/spec/schemas/dashboardv2.jsonschema.json +3387 -0
- package/src/spec/schemas/expr.jsonschema.json +987 -0
- package/src/spec/schemas/geomap.jsonschema.json +220 -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.ts +22 -10
- 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 +428 -0
- package/src/validate-output.ts +332 -101
- package/src/validate.ts +14 -0
- package/src/variables.ts +7 -2
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reading v2 dashboards (#2947): the key tables against the vendored
|
|
3
|
+
* dashboardv2 schema, the conversion against Grafana's own v1 read of the
|
|
4
|
+
* same dashboard, and a warning for everything v2 says that the classic
|
|
5
|
+
* model cannot.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { describe, expect, test } from "vitest";
|
|
9
|
+
import { loadVendoredSchema } from "../spec/schemas";
|
|
10
|
+
import { normalizeDashboard } from "./normalize";
|
|
11
|
+
import { parseGrafana, type DashboardResourceMetadata } from "./parser";
|
|
12
|
+
import { V2_KEYS, lossyV1Read, readV2Dashboard } from "./v2";
|
|
13
|
+
import { LOSSY_V1_EXPORT, V2_EXPORTS, read } from "./testdata/fixtures";
|
|
14
|
+
|
|
15
|
+
type Json = Record<string, unknown>;
|
|
16
|
+
|
|
17
|
+
const json = (file: string): Json => JSON.parse(read(file)) as Json;
|
|
18
|
+
const TABS = "exports/grafana-13.2.2/tabs.v2-resource.json";
|
|
19
|
+
const CHECKOUT = "exports/grafana-13.2.2/checkout.v2-resource.json";
|
|
20
|
+
|
|
21
|
+
/** A bare v2 spec with one grid panel, for the synthetic cases. */
|
|
22
|
+
function spec(over: Json = {}): Json {
|
|
23
|
+
return {
|
|
24
|
+
title: "Synthetic",
|
|
25
|
+
annotations: [],
|
|
26
|
+
cursorSync: "Off",
|
|
27
|
+
links: [],
|
|
28
|
+
preload: false,
|
|
29
|
+
tags: [],
|
|
30
|
+
variables: [],
|
|
31
|
+
timeSettings: { from: "now-1h", to: "now", autoRefresh: "", autoRefreshIntervals: [], hideTimepicker: false, fiscalYearStartMonth: 0 },
|
|
32
|
+
elements: { "panel-1": panel(1, "One") },
|
|
33
|
+
layout: grid(["panel-1"]),
|
|
34
|
+
...over,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function panel(id: number, title: string, extra: Json = {}): Json {
|
|
39
|
+
return {
|
|
40
|
+
kind: "Panel",
|
|
41
|
+
spec: {
|
|
42
|
+
id,
|
|
43
|
+
title,
|
|
44
|
+
description: "",
|
|
45
|
+
links: [],
|
|
46
|
+
data: {
|
|
47
|
+
kind: "QueryGroup",
|
|
48
|
+
spec: {
|
|
49
|
+
queries: [
|
|
50
|
+
{
|
|
51
|
+
kind: "PanelQuery",
|
|
52
|
+
spec: {
|
|
53
|
+
query: { kind: "DataQuery", group: "prometheus", version: "v0", datasource: { name: "prom" }, spec: { expr: "up" } },
|
|
54
|
+
refId: "A",
|
|
55
|
+
hidden: false,
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
transformations: [],
|
|
60
|
+
queryOptions: {},
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
vizConfig: { kind: "VizConfig", group: "timeseries", version: "", spec: { options: {}, fieldConfig: { defaults: {}, overrides: [] } } },
|
|
64
|
+
...extra,
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function grid(names: string[], extra: Json = {}): Json {
|
|
70
|
+
return {
|
|
71
|
+
kind: "GridLayout",
|
|
72
|
+
spec: {
|
|
73
|
+
items: names.map((name, i) => ({ kind: "GridLayoutItem", spec: { x: 0, y: i * 8, width: 24, height: 8, element: { kind: "ElementReference", name }, ...extra } })),
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
describe("the key tables and the vendored dashboardv2 schema", () => {
|
|
79
|
+
const defs = loadVendoredSchema("dashboardv2").definitions as Record<string, { properties?: Json }>;
|
|
80
|
+
|
|
81
|
+
for (const [def, table] of Object.entries(V2_KEYS)) {
|
|
82
|
+
test(`${def}: every key the schema defines is carried or reported, and no other`, () => {
|
|
83
|
+
expect(defs[def], def).toBeDefined();
|
|
84
|
+
const schemaKeys = Object.keys(defs[def].properties ?? {}).sort();
|
|
85
|
+
expect([...table.carried, ...Object.keys(table.reported)].sort()).toEqual(schemaKeys);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
test("every variable kind the schema has is read", () => {
|
|
90
|
+
const kinds = (defs.VariableKind as unknown as { oneOf: Array<{ $ref: string }> }).oneOf.map((r) => r.$ref.replace("#/definitions/", "").replace(/Kind$/, "Spec"));
|
|
91
|
+
for (const spec of kinds) expect(V2_KEYS[spec], spec).toBeDefined();
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
test("every layout kind the schema has is read", () => {
|
|
95
|
+
const layouts = (defs.Dashboard.properties!.layout as { oneOf: Array<{ $ref: string }> }).oneOf.map((r) => r.$ref.replace("#/definitions/", ""));
|
|
96
|
+
expect(layouts.sort()).toEqual(["AutoGridLayoutKind", "GridLayoutKind", "RowsLayoutKind", "TabsLayoutKind"]);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
describe("a v2 dashboard read as classic JSON", () => {
|
|
101
|
+
test("gives what Grafana 13.2.2 serves for the same dashboard at v1, but for what is reported", () => {
|
|
102
|
+
const { dashboard } = readV2Dashboard(json(TABS));
|
|
103
|
+
const grafana = (json(LOSSY_V1_EXPORT).spec as Json) ?? {};
|
|
104
|
+
// Grafana writes "show in controls menu" as hide 3, which chant has no value for; the importer reports it and leaves it out.
|
|
105
|
+
const expected = structuredClone(grafana);
|
|
106
|
+
const list = (expected.templating as { list: Json[] }).list;
|
|
107
|
+
delete list.find((v) => v.name === "job")!.hide;
|
|
108
|
+
expect(normalizeDashboard(dashboard)).toEqual(normalizeDashboard({ ...expected, uid: "chant-fx-tabs" }));
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test("the checkout V2 Resource export carries every panel and variable the Classic export of it has", () => {
|
|
112
|
+
const { dashboard } = readV2Dashboard(json(CHECKOUT));
|
|
113
|
+
const classic = json("exports/grafana-13.2.2/checkout.json");
|
|
114
|
+
const leaves = (d: Json): Json[] => (d.panels as Json[]).flatMap((p) => (p.type === "row" ? ((p.panels as Json[] | undefined) ?? []) : [p]));
|
|
115
|
+
const byId = (d: Json) => new Map(leaves(normalizeDashboard(d)).map((p) => [p.id, p]));
|
|
116
|
+
// v2 keeps a threshold's base step as value: null, which the classic export leaves out.
|
|
117
|
+
const strip = (v: unknown): unknown => JSON.parse(JSON.stringify(v, (k, x) => (k === "value" && x === null ? undefined : x)));
|
|
118
|
+
const mine = byId(dashboard);
|
|
119
|
+
const theirs = byId(classic);
|
|
120
|
+
expect([...mine.keys()].sort()).toEqual([...theirs.keys()].sort());
|
|
121
|
+
for (const [id, p] of theirs) {
|
|
122
|
+
const q = mine.get(id)!;
|
|
123
|
+
for (const key of ["type", "title", "options", "targets", "transformations", "datasource", "links", "repeat", "repeatDirection", "maxPerRow"]) {
|
|
124
|
+
expect({ id, key, value: q[key] }).toEqual({ id, key, value: p[key] });
|
|
125
|
+
}
|
|
126
|
+
expect(strip(q.fieldConfig)).toEqual(strip(p.fieldConfig));
|
|
127
|
+
}
|
|
128
|
+
const vars = (d: Json) =>
|
|
129
|
+
((normalizeDashboard(d).templating as { list: Json[] }).list).map(({ current: _c, ...rest }) => rest);
|
|
130
|
+
expect(vars(dashboard).map((v) => v.name)).toEqual(vars(classic).map((v) => v.name));
|
|
131
|
+
for (const key of ["title", "tags", "links", "time", "timezone", "editable"]) expect({ key, v: dashboard[key] }).toEqual({ key, v: classic[key] });
|
|
132
|
+
// A collapsed row keeps its repeat, and the panel after it in the Classic export sits inside it in v2.
|
|
133
|
+
const row = (dashboard.panels as Json[]).find((p) => p.type === "row")!;
|
|
134
|
+
expect(row).toMatchObject({ title: "Details for $job", collapsed: true, repeat: "job" });
|
|
135
|
+
expect((row.panels as Json[]).map((p) => p.id)).toEqual([4, 5]);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
test("names every v2-only feature of the tabs dashboard", () => {
|
|
139
|
+
const { warnings } = readV2Dashboard(json(TABS));
|
|
140
|
+
expect(warnings).toEqual([
|
|
141
|
+
'layout: the dashboard\'s tabs "Overview" and "Details" become expanded rows, since a classic dashboard has no tabs: every tab\'s panels show on one page, one after another',
|
|
142
|
+
'layout: the tab "Overview" is an auto grid, which a classic dashboard does not have. Its 2 panels are placed on a fixed grid, 2 to a row at 12x5, as Grafana places them when it reads the dashboard at v1, and no longer resize with the screen',
|
|
143
|
+
'layout: a panel in the tab "Overview": conditionalRendering is not carried (conditional rendering has no classic form, so the panel always shows)',
|
|
144
|
+
'layout: the rows inside the tab "Details" come after its row as rows of their own, since classic rows do not nest',
|
|
145
|
+
'layout: the row "Logs": fillScreen is not carried (a classic row does not stretch to fill the screen)',
|
|
146
|
+
'layout: the row "Logs": conditionalRendering is not carried (conditional rendering has no classic form, so the row always shows)',
|
|
147
|
+
'variable "job": hide is not carried (it shows in the controls menu, which a classic dashboard does not have, so it shows in the variable bar)',
|
|
148
|
+
]);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
test("an export with nothing v2-only reads without a v2 warning", () => {
|
|
152
|
+
expect(readV2Dashboard(json(CHECKOUT)).warnings).toEqual([]);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
test("tabs become rows, in order, and an auto grid gets Grafana's fixed positions", () => {
|
|
156
|
+
const panels = readV2Dashboard(json(TABS)).dashboard.panels as Json[];
|
|
157
|
+
expect(panels.map((p) => [p.type, p.id, p.title, p.gridPos])).toEqual([
|
|
158
|
+
["row", 5, "Overview", { h: 1, w: 24, x: 0, y: 0 }],
|
|
159
|
+
["stat", 1, "Availability", { h: 5, w: 12, x: 0, y: 1 }],
|
|
160
|
+
["timeseries", 2, "Request rate", { h: 5, w: 12, x: 12, y: 1 }],
|
|
161
|
+
["row", 6, "Details", { h: 1, w: 24, x: 0, y: 6 }],
|
|
162
|
+
["row", 7, "Latency ($env)", { h: 1, w: 24, x: 0, y: 7 }],
|
|
163
|
+
["timeseries", 3, "p99 latency", { h: 8, w: 24, x: 0, y: 8 }],
|
|
164
|
+
["row", 8, "Logs", { h: 1, w: 24, x: 0, y: 16 }],
|
|
165
|
+
]);
|
|
166
|
+
expect(panels[4].repeat).toBe("env");
|
|
167
|
+
expect((panels[6].panels as Json[]).map((p) => [p.id, p.gridPos])).toEqual([[4, { h: 10, w: 24, x: 0, y: 17 }]]);
|
|
168
|
+
// Query options, a hidden query and a disabled transformation become the classic keys.
|
|
169
|
+
expect(panels[2]).toMatchObject({ maxDataPoints: 500, interval: "30s", timeFrom: "1h", pluginVersion: "13.2.2" });
|
|
170
|
+
expect((panels[2].targets as Json[])[1]).toMatchObject({ refId: "B", hide: true });
|
|
171
|
+
expect(panels[2].transformations).toEqual([{ id: "organize", disabled: true, options: { renameByName: { total: "all" } } }]);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
test("a key the schema does not have is reported", () => {
|
|
175
|
+
const s = spec({ sparkle: true });
|
|
176
|
+
(s.elements as Json)["panel-1"] = panel(1, "One", { glow: 1 });
|
|
177
|
+
expect(readV2Dashboard(s).warnings).toEqual([
|
|
178
|
+
"dashboard: sparkle is not carried (not a key the dashboardv2 schema at the pin has)",
|
|
179
|
+
'panel "One" (id 1): glow is not carried (not a key the dashboardv2 schema at the pin has)',
|
|
180
|
+
]);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
test("an element no layout places, and one placed twice, are reported", () => {
|
|
184
|
+
const s = spec({ elements: { "panel-1": panel(1, "One"), "panel-2": panel(2, "Two") }, layout: grid(["panel-1", "panel-1"]) });
|
|
185
|
+
const { dashboard, warnings } = readV2Dashboard(s);
|
|
186
|
+
expect((dashboard.panels as Json[]).map((p) => p.id)).toEqual([1]);
|
|
187
|
+
expect(warnings).toEqual([
|
|
188
|
+
'layout: the dashboard places the element "panel-1" a second time; a classic dashboard holds each panel once, so the second is left out',
|
|
189
|
+
'elements: "panel-2" is not placed in the layout, so Grafana does not show it and it is left out',
|
|
190
|
+
]);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
test("a hidden row header is fine first, and reported after another row", () => {
|
|
194
|
+
const row = (title: string, name: string, hideHeader: boolean) => ({ kind: "RowsLayoutRow", spec: { title, collapse: false, hideHeader, layout: grid([name]) } });
|
|
195
|
+
const s = spec({
|
|
196
|
+
elements: { "panel-1": panel(1, "One"), "panel-2": panel(2, "Two"), "panel-3": panel(3, "Three") },
|
|
197
|
+
layout: { kind: "RowsLayout", spec: { rows: [row("", "panel-1", true), row("B", "panel-2", false), row("", "panel-3", true)] } },
|
|
198
|
+
});
|
|
199
|
+
const { dashboard, warnings } = readV2Dashboard(s);
|
|
200
|
+
expect((dashboard.panels as Json[]).map((p) => [p.type, p.id, (p.gridPos as Json).y])).toEqual([
|
|
201
|
+
["timeseries", 1, 0],
|
|
202
|
+
["row", 4, 8],
|
|
203
|
+
["timeseries", 2, 9],
|
|
204
|
+
["timeseries", 3, 17],
|
|
205
|
+
]);
|
|
206
|
+
expect(warnings).toEqual([
|
|
207
|
+
'layout: the row (untitled) has a hidden header, which a classic dashboard has only for the panels above its first row; here its panels follow the row before them, so they become part of that row',
|
|
208
|
+
]);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
test("a library panel element becomes a libraryPanel reference", () => {
|
|
212
|
+
const s = spec({ elements: { "panel-1": { kind: "LibraryPanel", spec: { id: 1, title: "Shared", libraryPanel: { uid: "lp", name: "Shared" } } } } });
|
|
213
|
+
expect((readV2Dashboard(s).dashboard.panels as Json[])[0]).toEqual({ id: 1, title: "Shared", gridPos: { h: 8, w: 24, x: 0, y: 0 }, libraryPanel: { uid: "lp", name: "Shared" } });
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
test("a grid item's repeat, a legacy string query and v2beta1 transformations", () => {
|
|
217
|
+
const p = panel(1, "One");
|
|
218
|
+
const data = ((p.spec as Json).data as Json).spec as Json;
|
|
219
|
+
(((data.queries as Json[])[0].spec as Json).query as Json).spec = { __legacyStringValue: "up", refId: "A" };
|
|
220
|
+
data.transformations = [{ kind: "reduce", spec: { id: "reduce", options: { reducers: ["max"] } } }];
|
|
221
|
+
const s = spec({ elements: { "panel-1": p }, layout: grid(["panel-1"], { repeat: { mode: "variable", value: "env", direction: "v", maxPerRow: 4 } }) });
|
|
222
|
+
const out = (readV2Dashboard(s).dashboard.panels as Json[])[0];
|
|
223
|
+
expect(out).toMatchObject({ repeat: "env", repeatDirection: "v", maxPerRow: 4, transformations: [{ id: "reduce", options: { reducers: ["max"] } }] });
|
|
224
|
+
expect(out.targets).toEqual([{ query: "up", refId: "A", datasource: { type: "prometheus", uid: "prom" } }]);
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
test("an auto grid with custom row heights rounds pixels up to grid units, as Grafana does", () => {
|
|
228
|
+
const s = spec({
|
|
229
|
+
layout: { kind: "AutoGridLayout", spec: { columnWidthMode: "standard", rowHeightMode: "custom", rowHeight: 200, items: [{ kind: "AutoGridLayoutItem", spec: { element: { kind: "ElementReference", name: "panel-1" } } }] } },
|
|
230
|
+
});
|
|
231
|
+
expect((readV2Dashboard(s).dashboard.panels as Json[])[0].gridPos).toEqual({ h: 6, w: 8, x: 0, y: 0 });
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
test("v2alpha1 is refused, with where to read it instead", () => {
|
|
235
|
+
expect(() => readV2Dashboard({ apiVersion: "dashboard.grafana.app/v2alpha1", kind: "Dashboard", metadata: { name: "x" }, spec: spec() })).toThrow(
|
|
236
|
+
/dashboard\.grafana\.app\/v2alpha1 dashboard; chant reads v2 and v2beta1/,
|
|
237
|
+
);
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
test("a folder annotation is reported", () => {
|
|
241
|
+
const r = readV2Dashboard({ apiVersion: "dashboard.grafana.app/v2", kind: "Dashboard", metadata: { name: "x", annotations: { "grafana.app/folder": "ops" } }, spec: spec() });
|
|
242
|
+
expect(r.warnings).toEqual(['metadata: the folder "ops" is not carried (a dashboard\'s folder is set where it is provisioned)']);
|
|
243
|
+
expect(r.dashboard.uid).toBe("x");
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
describe("the parser", () => {
|
|
248
|
+
for (const file of V2_EXPORTS) {
|
|
249
|
+
test(`imports ${file}, with the classic form as the round trip's source`, () => {
|
|
250
|
+
const ir = parseGrafana(read(file));
|
|
251
|
+
expect(ir.resources).toHaveLength(1);
|
|
252
|
+
expect(ir.warnings?.[0]).toMatch(/^This is a v2 dashboard \(dashboard\.grafana\.app\/v2\)\. chant builds classic \(v1\) dashboard JSON/);
|
|
253
|
+
const meta = ir.resources[0].metadata as unknown as DashboardResourceMetadata;
|
|
254
|
+
expect(meta.v2).toEqual(json(file));
|
|
255
|
+
expect(meta.source).toEqual(readV2Dashboard(json(file)).dashboard);
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
test("a bare v2 spec imports too", () => {
|
|
260
|
+
const ir = parseGrafana(JSON.stringify(spec()));
|
|
261
|
+
expect(ir.resources).toHaveLength(1);
|
|
262
|
+
expect(ir.warnings?.[0]).toMatch(/^This is a v2 dashboard\. /);
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
test("a v1 read of a dashboard stored as v2 is refused", () => {
|
|
266
|
+
const ir = parseGrafana(read(LOSSY_V1_EXPORT));
|
|
267
|
+
expect(ir.resources).toEqual([]);
|
|
268
|
+
expect(ir.warnings).toEqual([
|
|
269
|
+
expect.stringMatching(
|
|
270
|
+
/^Not imported: Grafana stores this dashboard as v2 and converted it down to serve it at dashboard\.grafana\.app\/v1, .* Read the dashboard at dashboard\.grafana\.app\/v2 .* acceptLossyV1\.$/,
|
|
271
|
+
),
|
|
272
|
+
]);
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
test("with acceptLossyV1 it is imported, and the warning says what it is", () => {
|
|
276
|
+
const ir = parseGrafana(read(LOSSY_V1_EXPORT), { acceptLossyV1: true });
|
|
277
|
+
expect(ir.resources).toHaveLength(1);
|
|
278
|
+
expect(ir.warnings?.[0]).toMatch(/^Grafana stores this dashboard as v2, and this dashboard\.grafana\.app\/v1 copy is a lossy down-conversion of it/);
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
test("a failed conversion is refused the same way", () => {
|
|
282
|
+
const resource = { ...json(LOSSY_V1_EXPORT), status: { conversion: { failed: true, storedVersion: "v2" } } };
|
|
283
|
+
expect(parseGrafana(JSON.stringify(resource)).warnings?.[0]).toMatch(/^Not imported: Grafana could not convert it from v2 \(status\.conversion\.failed\)/);
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
test("a v1 read of a dashboard stored as v0 or v1 is not lossy", () => {
|
|
287
|
+
const resource = { ...json(LOSSY_V1_EXPORT), status: { conversion: { failed: false, storedVersion: "v0alpha1" } } };
|
|
288
|
+
expect(lossyV1Read(resource)).toBeUndefined();
|
|
289
|
+
expect(lossyV1Read(json(LOSSY_V1_EXPORT))).toEqual({ apiVersion: "dashboard.grafana.app/v1", storedVersion: "v2", failed: false });
|
|
290
|
+
expect(parseGrafana(JSON.stringify(resource)).resources).toHaveLength(1);
|
|
291
|
+
});
|
|
292
|
+
});
|