@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
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live export (#2946) against an in-memory Grafana: the IR goes through the
|
|
3
|
+
* importer's generator unchanged, and a dashboard exported from Grafana
|
|
4
|
+
* generates the same source as the same JSON given to `chant import`.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { describe, expect, it } from "vitest";
|
|
8
|
+
import { readFileSync } from "node:fs";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { exportResources } from "./export-resources";
|
|
11
|
+
import { fakeGrafana, liveDatasource, type FakeGrafanaState } from "./api/fake-grafana";
|
|
12
|
+
import { GrafanaGenerator } from "./import/generator";
|
|
13
|
+
import { parseGrafana } from "./import/parser";
|
|
14
|
+
import { grafanaPlugin } from "./plugin";
|
|
15
|
+
import { datasourceProps } from "./import/live-export";
|
|
16
|
+
|
|
17
|
+
const CONFIG = { grafana: { profiles: { prod: { url: "http://grafana.test" } } } };
|
|
18
|
+
|
|
19
|
+
const board = {
|
|
20
|
+
title: "Checkout",
|
|
21
|
+
tags: ["shop"],
|
|
22
|
+
graphTooltip: 1,
|
|
23
|
+
schemaVersion: 41,
|
|
24
|
+
panels: [
|
|
25
|
+
{
|
|
26
|
+
type: "timeseries",
|
|
27
|
+
id: 1,
|
|
28
|
+
title: "Requests",
|
|
29
|
+
gridPos: { h: 8, w: 12, x: 0, y: 0 },
|
|
30
|
+
datasource: { type: "prometheus", uid: "prom" },
|
|
31
|
+
targets: [{ refId: "A", expr: "sum(rate(http_requests_total[5m]))", datasource: { type: "prometheus", uid: "prom" } }],
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
function state(overrides: Partial<FakeGrafanaState> = {}): FakeGrafanaState {
|
|
37
|
+
return {
|
|
38
|
+
api: "v1",
|
|
39
|
+
dashboards: {
|
|
40
|
+
checkout: { spec: board, annotations: { "grafana.app/managedBy": "classic-file-provisioning", "grafana.app/managerId": "chant" } },
|
|
41
|
+
"hand-made": { spec: { title: "Hand made", panels: [] } },
|
|
42
|
+
},
|
|
43
|
+
datasources: {
|
|
44
|
+
prom: liveDatasource({ name: "Prom", type: "prometheus", uid: "prom", url: "http://prometheus:9090", isDefault: true, secure: ["basicAuthPassword"] }),
|
|
45
|
+
},
|
|
46
|
+
...overrides,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const exportFrom = (s: FakeGrafanaState, opts: Partial<Parameters<typeof exportResources>[0]> = {}) =>
|
|
51
|
+
exportResources({ environment: "prod", config: CONFIG, env: {}, http: fakeGrafana(s), ...opts });
|
|
52
|
+
|
|
53
|
+
describe("exportResources", () => {
|
|
54
|
+
it("is wired on the plugin", () => {
|
|
55
|
+
expect(typeof grafanaPlugin.exportResources).toBe("function");
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it("feeds the importer's generator unchanged, and generates what chant import writes for the same JSON", async () => {
|
|
59
|
+
const ir = await exportFrom(state(), { selector: { type: "Grafana::Dashboard", name: "checkout" } });
|
|
60
|
+
const exported = new GrafanaGenerator().generate(ir);
|
|
61
|
+
const imported = new GrafanaGenerator().generate(parseGrafana(JSON.stringify({ ...board, uid: "checkout" })));
|
|
62
|
+
expect(exported).toEqual(imported);
|
|
63
|
+
expect(exported.map((f) => f.path)).toEqual(expect.arrayContaining([expect.stringMatching(/^checkout\/dashboard\.ts$/)]));
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it("exports every dashboard and datasource, secrets as key names only", async () => {
|
|
67
|
+
const ir = await exportFrom(state());
|
|
68
|
+
expect(ir.resources.map((r) => `${r.type}:${r.logicalId}`).sort()).toEqual(["Grafana::Dashboard:checkout", "Grafana::Dashboard:handMade", "Grafana::Provisioning:datasources"]);
|
|
69
|
+
const files = new GrafanaGenerator().generate(ir);
|
|
70
|
+
const ds = files.find((f) => f.path === "datasources.ts")!.content;
|
|
71
|
+
expect(ds).toContain('basicAuthPassword: "[REDACTED]"');
|
|
72
|
+
expect(ir.warnings?.join("\n")).toMatch(/\[REDACTED\]/);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it("a dashboard refers to a datasource exported beside it by uid, rather than declaring it again", async () => {
|
|
76
|
+
const files = new GrafanaGenerator().generate(await exportFrom(state()));
|
|
77
|
+
const dashboardDatasources = files.find((f) => f.path === "checkout/datasources.ts")!.content;
|
|
78
|
+
expect(dashboardDatasources).not.toContain("ExternalDatasource");
|
|
79
|
+
expect(dashboardDatasources).toMatch(/const prom: DatasourceRef<"prometheus"> = \{ type: "prometheus", uid: "prom" \}/);
|
|
80
|
+
expect(files.find((f) => f.path === "datasources.ts")!.content).toContain("new Datasource(");
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it("owned keeps only chant's dashboards and no datasources", async () => {
|
|
84
|
+
const ir = await exportFrom(state(), { owned: true });
|
|
85
|
+
expect(ir.resources.map((r) => r.logicalId)).toEqual(["checkout"]);
|
|
86
|
+
expect(ir.warnings?.join("\n")).toMatch(/datasources are not exported with --owned/);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it("reads the legacy API on a server without dashboard.grafana.app", async () => {
|
|
90
|
+
const ir = await exportFrom(state({ api: "legacy" }), { selector: { name: "checkout" } });
|
|
91
|
+
expect(ir.resources.map((r) => r.logicalId)).toEqual(["checkout"]);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("leaves out a v2-stored dashboard the server does not serve at v2, and says so", async () => {
|
|
95
|
+
const s = state();
|
|
96
|
+
s.dashboards.checkout.storedVersion = "v2beta1";
|
|
97
|
+
const ir = await exportFrom(s, { selector: { type: "Grafana::Dashboard" } });
|
|
98
|
+
expect(ir.resources.map((r) => r.logicalId)).toEqual(["handMade"]);
|
|
99
|
+
expect(ir.warnings?.join("\n")).toMatch(/checkout is not exported: it is stored as a v2beta1 dashboard .* lossy down-conversion/);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it("exports a v2-stored dashboard through its v2 read, as chant import of the same v2 JSON does (#2947)", async () => {
|
|
103
|
+
const fixture = JSON.parse(readFileSync(join(import.meta.dirname, "..", "test", "fixtures", "exports", "grafana-13.2.2", "tabs.v2-resource.json"), "utf-8")) as { spec: Record<string, unknown> };
|
|
104
|
+
const s = state();
|
|
105
|
+
s.dashboards.checkout = { ...s.dashboards.checkout, storedVersion: "v2", v2: fixture.spec };
|
|
106
|
+
const ir = await exportFrom(s, { selector: { type: "Grafana::Dashboard", name: "checkout" } });
|
|
107
|
+
expect(ir.resources.map((r) => r.logicalId)).toEqual(["checkoutTabs"]);
|
|
108
|
+
expect(ir.warnings).toContainEqual(expect.stringMatching(/^dashboard checkout is stored as v2 and exported in the classic model: layout: the dashboard's tabs "Overview" and "Details" become expanded rows/));
|
|
109
|
+
const exported = new GrafanaGenerator().generate(ir);
|
|
110
|
+
const imported = new GrafanaGenerator().generate(parseGrafana(JSON.stringify({ ...fixture, metadata: { name: "checkout" } })));
|
|
111
|
+
expect(exported).toEqual(imported);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it("fails loudly when there is no Grafana to read", async () => {
|
|
115
|
+
await expect(exportResources({ environment: "staging", config: CONFIG, env: {} })).rejects.toThrow(/GRAFANA_URL/);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
describe("datasourceProps", () => {
|
|
120
|
+
const live = liveDatasource({ name: "Prom", type: "prometheus", uid: "prom", url: "http://p:9090", secure: ["password"] });
|
|
121
|
+
|
|
122
|
+
it("keeps what somebody set, and names secrets without their values", () => {
|
|
123
|
+
expect(datasourceProps(live)).toEqual({ name: "Prom", type: "prometheus", uid: "prom", url: "http://p:9090", secureJsonData: { password: "[REDACTED]" } });
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it("keeps the API's defaults under verbatim, and editable from readOnly", () => {
|
|
127
|
+
expect(datasourceProps({ ...live, readOnly: false }, { keepDefaults: true })).toMatchObject({ access: "proxy", isDefault: false, editable: true });
|
|
128
|
+
});
|
|
129
|
+
});
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live export for grafana (#2946): `chant import --from <env>` writes the
|
|
3
|
+
* environment's dashboards and datasources as chant TypeScript.
|
|
4
|
+
*
|
|
5
|
+
* All I/O is here; the mapping is pure in ./import/live-export.ts, and the
|
|
6
|
+
* IR it builds is the importer's own (#2945), so a dashboard exported from
|
|
7
|
+
* Grafana and the same dashboard's JSON given to `chant import` generate the
|
|
8
|
+
* same source through the same `GrafanaGenerator`.
|
|
9
|
+
*
|
|
10
|
+
* - Every dashboard in the organisation is listed over the API the thin
|
|
11
|
+
* read uses (`/apis/dashboard.grafana.app`, or `/api/search` plus
|
|
12
|
+
* `/api/dashboards/uid` on Grafana 11). A dashboard stored as v2 is read at
|
|
13
|
+
* v2 and exported through its classic form, with a warning for each thing
|
|
14
|
+
* the classic form cannot hold (#2947).
|
|
15
|
+
* - Every datasource is read by uid, for `secureJsonFields`; secrets come
|
|
16
|
+
* back as key names only (see `datasourceProps`).
|
|
17
|
+
* - `selector.type` is `Grafana::Dashboard` or `Grafana::Datasource`;
|
|
18
|
+
* `selector.name` is a uid.
|
|
19
|
+
* - `owned` keeps only dashboards that are chant's (./ownership.ts), and
|
|
20
|
+
* leaves datasources out, since their ownership cannot be read. There is no
|
|
21
|
+
* project here to name its providers, so a file-provisioned dashboard is
|
|
22
|
+
* chant's when its provider is the default one, `chant`.
|
|
23
|
+
* - `verbatim` keeps datasource keys at the API's "not set" values. A
|
|
24
|
+
* dashboard is always planned by the importer, which leaves out keys at
|
|
25
|
+
* Grafana's defaults either way.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
import type { ExportedTemplate, ResourceSelector } from "@intentius/chant/lexicon";
|
|
29
|
+
import { bindGrafana, type BindOptions } from "./api/bind";
|
|
30
|
+
import { classicDashboardOf, listDashboards } from "./api/dashboards";
|
|
31
|
+
import { listDatasources, readDatasource } from "./api/datasources";
|
|
32
|
+
import { DASHBOARD_TYPE } from "./dashboard";
|
|
33
|
+
import { DATASOURCE_TYPE } from "./datasource";
|
|
34
|
+
import { exportTemplate } from "./import/live-export";
|
|
35
|
+
import { DEFAULT_PROVIDER_NAME, dashboardOwnership } from "./ownership";
|
|
36
|
+
|
|
37
|
+
type Json = Record<string, unknown>;
|
|
38
|
+
|
|
39
|
+
export interface GrafanaExportOptions extends Omit<BindOptions, "environment"> {
|
|
40
|
+
environment: string;
|
|
41
|
+
stack?: string;
|
|
42
|
+
region?: string;
|
|
43
|
+
selector?: ResourceSelector;
|
|
44
|
+
owned?: boolean;
|
|
45
|
+
verbatim?: boolean;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export async function exportResources(options: GrafanaExportOptions): Promise<ExportedTemplate> {
|
|
49
|
+
const client = await bindGrafana({ ...options });
|
|
50
|
+
const type = options.selector?.type;
|
|
51
|
+
const name = options.selector?.name;
|
|
52
|
+
const warnings: string[] = [];
|
|
53
|
+
|
|
54
|
+
const dashboards: Array<{ json: Json }> = [];
|
|
55
|
+
if (type === undefined || type === DASHBOARD_TYPE) {
|
|
56
|
+
const providers = new Set([DEFAULT_PROVIDER_NAME]);
|
|
57
|
+
for (const live of await listDashboards(client)) {
|
|
58
|
+
if (name !== undefined && live.uid !== name) continue;
|
|
59
|
+
if (options.owned && dashboardOwnership(live, providers).ownership !== "owned") continue;
|
|
60
|
+
const classic = classicDashboardOf(live);
|
|
61
|
+
if ("unsupported" in classic) {
|
|
62
|
+
warnings.push(`dashboard ${live.uid} is not exported: ${classic.unsupported}`);
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
for (const w of classic.warnings ?? []) warnings.push(`dashboard ${live.uid} is stored as v2 and exported in the classic model: ${w}`);
|
|
66
|
+
dashboards.push({ json: classic.json });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const datasources: Json[] = [];
|
|
71
|
+
if ((type === undefined || type === DATASOURCE_TYPE) && !options.owned) {
|
|
72
|
+
for (const summary of await listDatasources(client)) {
|
|
73
|
+
const uid = typeof summary.uid === "string" ? summary.uid : undefined;
|
|
74
|
+
if (!uid || (name !== undefined && uid !== name)) continue;
|
|
75
|
+
const read = await readDatasource(client, uid);
|
|
76
|
+
if ("present" in read) datasources.push(read.present);
|
|
77
|
+
}
|
|
78
|
+
} else if (options.owned && (type === undefined || type === DATASOURCE_TYPE)) {
|
|
79
|
+
warnings.push("datasources are not exported with --owned: Grafana's datasource API carries no ownership marker");
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const ir = exportTemplate({ dashboards, datasources, keepDefaults: options.verbatim });
|
|
83
|
+
return { ...ir, warnings: [...warnings, ...(ir.warnings ?? [])] };
|
|
84
|
+
}
|
package/src/folder.ts
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `Folder`: a Grafana folder with a stable uid, nested with `parent`.
|
|
3
|
+
*
|
|
4
|
+
* A dashboard names its folder either as a path string
|
|
5
|
+
* (`folder: "Platform/Kubernetes"`) or as a `Folder`. Both give the same
|
|
6
|
+
* folders: one per level, each with the uid `folderUidFor` makes from its
|
|
7
|
+
* path unless a `Folder` sets one. A `Folder` is needed only to pin a uid
|
|
8
|
+
* (for links, alert rules, permissions set elsewhere) or to declare a folder
|
|
9
|
+
* that holds no dashboard yet.
|
|
10
|
+
*
|
|
11
|
+
* How each delivery carries it:
|
|
12
|
+
*
|
|
13
|
+
* - File provisioning writes the dashboard under `dashboards/<level>/...`,
|
|
14
|
+
* and a provider with `foldersFromFilesStructure` makes one folder per
|
|
15
|
+
* level (nested on Grafana 13.1 and later; GRAF109 says what earlier
|
|
16
|
+
* versions do). Grafana finds each level's folder by title under its
|
|
17
|
+
* parent and creates it when missing, with a uid of its own: file
|
|
18
|
+
* provisioning has no field for a nested folder's uid. A folder the API
|
|
19
|
+
* applier made first keeps the uid it was given. A `DashboardProvider`
|
|
20
|
+
* whose `folder` is a root-level `Folder` writes its `folderUid`.
|
|
21
|
+
* - The API applier (./api/apply.ts) creates every folder with its uid and
|
|
22
|
+
* parent, parents first.
|
|
23
|
+
* - Observation reads a dashboard's folder back as its path, and a `Folder`
|
|
24
|
+
* by its uid.
|
|
25
|
+
*
|
|
26
|
+
* The rules for turning folders into uids and parents are in one place,
|
|
27
|
+
* `resolveFolders` in ./api/folders.ts, which the build, the applier and
|
|
28
|
+
* observation all call.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
import { createResource } from "@intentius/chant/runtime";
|
|
32
|
+
import type { Declarable } from "@intentius/chant/declarable";
|
|
33
|
+
import { slugUid } from "./util";
|
|
34
|
+
|
|
35
|
+
export interface FolderProps {
|
|
36
|
+
/** The title Grafana shows. A single level: nest with `parent`, not with `/`. */
|
|
37
|
+
title: string;
|
|
38
|
+
/**
|
|
39
|
+
* Stable id: letters, digits, `-` and `_`, at most 40 characters, and not
|
|
40
|
+
* `general`, which Grafana keeps for its root. Defaults to the folder's
|
|
41
|
+
* path as a uid (`Platform/Kubernetes` becomes `platform-kubernetes`), the
|
|
42
|
+
* same uid a dashboard's `folder: "Platform/Kubernetes"` gives it.
|
|
43
|
+
*/
|
|
44
|
+
uid?: string;
|
|
45
|
+
/** The folder this one is in. Leave it out for a folder at the root. */
|
|
46
|
+
parent?: FolderEntity;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface FolderEntity extends Declarable {
|
|
50
|
+
readonly props: FolderProps;
|
|
51
|
+
/** The uid Grafana gives the folder: its own, else one made from its path. */
|
|
52
|
+
readonly uid: string;
|
|
53
|
+
/** Its titles from the root, joined with `/`: the directory the build writes it to. */
|
|
54
|
+
readonly path: string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export const FOLDER_TYPE = "Grafana::Folder";
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* The levels of a folder path, as the build writes them to directories:
|
|
61
|
+
* split on `/`, a backslash made `-`, leading dots and surrounding blanks
|
|
62
|
+
* dropped, so no level names a directory outside `dashboards/`. Empty levels
|
|
63
|
+
* are dropped; no levels at all is the General folder.
|
|
64
|
+
*/
|
|
65
|
+
export function folderLevels(path: string): string[] {
|
|
66
|
+
return path
|
|
67
|
+
.split("/")
|
|
68
|
+
.map((level) => level.replace(/\\+/g, "-").trim().replace(/^\.+/, "").trim())
|
|
69
|
+
.filter((level) => level !== "");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** The uid chant gives a folder it only knows by path. Stable, so a second apply finds the folder the first one made. */
|
|
73
|
+
export function folderUidFor(path: string): string {
|
|
74
|
+
return slugUid(folderLevels(path).join("/"));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const Base = createResource(FOLDER_TYPE, "grafana", {}) as unknown as (this: object, props: Record<string, unknown>) => void;
|
|
78
|
+
|
|
79
|
+
/** A Grafana folder. */
|
|
80
|
+
export const Folder = function (this: object, props: FolderProps) {
|
|
81
|
+
const title = props.title;
|
|
82
|
+
if (typeof title !== "string" || folderLevels(title).length !== 1 || folderLevels(title)[0] !== title) {
|
|
83
|
+
throw new Error(
|
|
84
|
+
`grafana: Folder title ${JSON.stringify(title)} is not one folder level: use parent to nest folders, and leave out "/", "\\", leading dots and surrounding blanks, which file provisioning cannot write as a directory`,
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
if (props.parent !== undefined && !isFolderEntity(props.parent)) throw new Error(`grafana: Folder "${title}" has a parent that is not a Folder`);
|
|
88
|
+
Base.call(this, props as unknown as Record<string, unknown>);
|
|
89
|
+
const path = props.parent ? `${props.parent.path}/${title}` : title;
|
|
90
|
+
Object.defineProperty(this, "path", { value: path, enumerable: false });
|
|
91
|
+
Object.defineProperty(this, "uid", { value: props.uid ?? folderUidFor(path), enumerable: false });
|
|
92
|
+
} as unknown as new (props: FolderProps) => FolderEntity;
|
|
93
|
+
Object.defineProperty(Folder, "name", { value: "Folder" });
|
|
94
|
+
|
|
95
|
+
export function isFolderEntity(value: unknown): value is FolderEntity {
|
|
96
|
+
return (
|
|
97
|
+
typeof value === "object" &&
|
|
98
|
+
value !== null &&
|
|
99
|
+
(value as Declarable).entityType === FOLDER_TYPE &&
|
|
100
|
+
(value as Declarable).lexicon === "grafana"
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** A folder's uid from its props, as observation sees them (the props of a `Folder`, parents included). */
|
|
105
|
+
export function folderUidOf(props: Record<string, unknown>): string | undefined {
|
|
106
|
+
if (typeof props.uid === "string" && props.uid !== "") return props.uid;
|
|
107
|
+
const path = folderPathOf(props);
|
|
108
|
+
return path ? folderUidFor(path) : undefined;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** A folder's path from its props, walking `parent`. */
|
|
112
|
+
export function folderPathOf(props: Record<string, unknown>): string | undefined {
|
|
113
|
+
if (typeof props.title !== "string") return undefined;
|
|
114
|
+
const parent = props.parent as { props?: Record<string, unknown> } | undefined;
|
|
115
|
+
if (!parent) return props.title;
|
|
116
|
+
const up = parent.props ? folderPathOf(parent.props) : undefined;
|
|
117
|
+
return up === undefined ? undefined : `${up}/${props.title}`;
|
|
118
|
+
}
|
|
@@ -1,9 +1,79 @@
|
|
|
1
1
|
{
|
|
2
|
+
"AdhocVariable": {
|
|
3
|
+
"resourceType": "Grafana::Variable::adhoc",
|
|
4
|
+
"kind": "resource",
|
|
5
|
+
"lexicon": "grafana"
|
|
6
|
+
},
|
|
7
|
+
"AlertListPanel": {
|
|
8
|
+
"resourceType": "Grafana::Panel::alertlist",
|
|
9
|
+
"kind": "resource",
|
|
10
|
+
"lexicon": "grafana"
|
|
11
|
+
},
|
|
12
|
+
"AlertQuery": {
|
|
13
|
+
"resourceType": "Grafana::AlertQuery",
|
|
14
|
+
"kind": "resource",
|
|
15
|
+
"lexicon": "grafana"
|
|
16
|
+
},
|
|
17
|
+
"AlertRule": {
|
|
18
|
+
"resourceType": "Grafana::AlertRule",
|
|
19
|
+
"kind": "resource",
|
|
20
|
+
"lexicon": "grafana"
|
|
21
|
+
},
|
|
22
|
+
"AlertRuleGroup": {
|
|
23
|
+
"resourceType": "Grafana::AlertRuleGroup",
|
|
24
|
+
"kind": "resource",
|
|
25
|
+
"lexicon": "grafana"
|
|
26
|
+
},
|
|
27
|
+
"AzureMonitorQuery": {
|
|
28
|
+
"resourceType": "Grafana::Query::grafana-azure-monitor-datasource",
|
|
29
|
+
"kind": "resource",
|
|
30
|
+
"lexicon": "grafana"
|
|
31
|
+
},
|
|
32
|
+
"BarChartPanel": {
|
|
33
|
+
"resourceType": "Grafana::Panel::barchart",
|
|
34
|
+
"kind": "resource",
|
|
35
|
+
"lexicon": "grafana"
|
|
36
|
+
},
|
|
37
|
+
"BarGaugePanel": {
|
|
38
|
+
"resourceType": "Grafana::Panel::bargauge",
|
|
39
|
+
"kind": "resource",
|
|
40
|
+
"lexicon": "grafana"
|
|
41
|
+
},
|
|
42
|
+
"BigQueryQuery": {
|
|
43
|
+
"resourceType": "Grafana::Query::grafana-bigquery-datasource",
|
|
44
|
+
"kind": "resource",
|
|
45
|
+
"lexicon": "grafana"
|
|
46
|
+
},
|
|
47
|
+
"CanvasPanel": {
|
|
48
|
+
"resourceType": "Grafana::Panel::canvas",
|
|
49
|
+
"kind": "resource",
|
|
50
|
+
"lexicon": "grafana"
|
|
51
|
+
},
|
|
52
|
+
"ClassicConditionsExpression": {
|
|
53
|
+
"resourceType": "Grafana::Expression::classic_conditions",
|
|
54
|
+
"kind": "resource",
|
|
55
|
+
"lexicon": "grafana"
|
|
56
|
+
},
|
|
57
|
+
"CloudMonitoringQuery": {
|
|
58
|
+
"resourceType": "Grafana::Query::stackdriver",
|
|
59
|
+
"kind": "resource",
|
|
60
|
+
"lexicon": "grafana"
|
|
61
|
+
},
|
|
62
|
+
"CloudWatchQuery": {
|
|
63
|
+
"resourceType": "Grafana::Query::cloudwatch",
|
|
64
|
+
"kind": "resource",
|
|
65
|
+
"lexicon": "grafana"
|
|
66
|
+
},
|
|
2
67
|
"ConstantVariable": {
|
|
3
68
|
"resourceType": "Grafana::Variable::constant",
|
|
4
69
|
"kind": "resource",
|
|
5
70
|
"lexicon": "grafana"
|
|
6
71
|
},
|
|
72
|
+
"ContactPoint": {
|
|
73
|
+
"resourceType": "Grafana::ContactPoint",
|
|
74
|
+
"kind": "resource",
|
|
75
|
+
"lexicon": "grafana"
|
|
76
|
+
},
|
|
7
77
|
"CustomVariable": {
|
|
8
78
|
"resourceType": "Grafana::Variable::custom",
|
|
9
79
|
"kind": "resource",
|
|
@@ -24,21 +94,61 @@
|
|
|
24
94
|
"kind": "resource",
|
|
25
95
|
"lexicon": "grafana"
|
|
26
96
|
},
|
|
97
|
+
"DatasourceProvisioning": {
|
|
98
|
+
"resourceType": "Grafana::DatasourceProvisioning",
|
|
99
|
+
"kind": "resource",
|
|
100
|
+
"lexicon": "grafana"
|
|
101
|
+
},
|
|
27
102
|
"DatasourceVariable": {
|
|
28
103
|
"resourceType": "Grafana::Variable::datasource",
|
|
29
104
|
"kind": "resource",
|
|
30
105
|
"lexicon": "grafana"
|
|
31
106
|
},
|
|
107
|
+
"ElasticsearchQuery": {
|
|
108
|
+
"resourceType": "Grafana::Query::elasticsearch",
|
|
109
|
+
"kind": "resource",
|
|
110
|
+
"lexicon": "grafana"
|
|
111
|
+
},
|
|
112
|
+
"ExternalDatasource": {
|
|
113
|
+
"resourceType": "Grafana::ExternalDatasource",
|
|
114
|
+
"kind": "resource",
|
|
115
|
+
"lexicon": "grafana"
|
|
116
|
+
},
|
|
117
|
+
"FlameGraphPanel": {
|
|
118
|
+
"resourceType": "Grafana::Panel::flamegraph",
|
|
119
|
+
"kind": "resource",
|
|
120
|
+
"lexicon": "grafana"
|
|
121
|
+
},
|
|
122
|
+
"Folder": {
|
|
123
|
+
"resourceType": "Grafana::Folder",
|
|
124
|
+
"kind": "resource",
|
|
125
|
+
"lexicon": "grafana"
|
|
126
|
+
},
|
|
32
127
|
"GaugePanel": {
|
|
33
128
|
"resourceType": "Grafana::Panel::gauge",
|
|
34
129
|
"kind": "resource",
|
|
35
130
|
"lexicon": "grafana"
|
|
36
131
|
},
|
|
132
|
+
"GeomapPanel": {
|
|
133
|
+
"resourceType": "Grafana::Panel::geomap",
|
|
134
|
+
"kind": "resource",
|
|
135
|
+
"lexicon": "grafana"
|
|
136
|
+
},
|
|
137
|
+
"GroupByVariable": {
|
|
138
|
+
"resourceType": "Grafana::Variable::groupby",
|
|
139
|
+
"kind": "resource",
|
|
140
|
+
"lexicon": "grafana"
|
|
141
|
+
},
|
|
37
142
|
"HeatmapPanel": {
|
|
38
143
|
"resourceType": "Grafana::Panel::heatmap",
|
|
39
144
|
"kind": "resource",
|
|
40
145
|
"lexicon": "grafana"
|
|
41
146
|
},
|
|
147
|
+
"HistogramPanel": {
|
|
148
|
+
"resourceType": "Grafana::Panel::histogram",
|
|
149
|
+
"kind": "resource",
|
|
150
|
+
"lexicon": "grafana"
|
|
151
|
+
},
|
|
42
152
|
"IntervalVariable": {
|
|
43
153
|
"resourceType": "Grafana::Variable::interval",
|
|
44
154
|
"kind": "resource",
|
|
@@ -54,26 +164,106 @@
|
|
|
54
164
|
"kind": "resource",
|
|
55
165
|
"lexicon": "grafana"
|
|
56
166
|
},
|
|
167
|
+
"MathExpression": {
|
|
168
|
+
"resourceType": "Grafana::Expression::math",
|
|
169
|
+
"kind": "resource",
|
|
170
|
+
"lexicon": "grafana"
|
|
171
|
+
},
|
|
172
|
+
"MSSQLQuery": {
|
|
173
|
+
"resourceType": "Grafana::Query::mssql",
|
|
174
|
+
"kind": "resource",
|
|
175
|
+
"lexicon": "grafana"
|
|
176
|
+
},
|
|
177
|
+
"MuteTiming": {
|
|
178
|
+
"resourceType": "Grafana::MuteTiming",
|
|
179
|
+
"kind": "resource",
|
|
180
|
+
"lexicon": "grafana"
|
|
181
|
+
},
|
|
182
|
+
"MySQLQuery": {
|
|
183
|
+
"resourceType": "Grafana::Query::mysql",
|
|
184
|
+
"kind": "resource",
|
|
185
|
+
"lexicon": "grafana"
|
|
186
|
+
},
|
|
187
|
+
"NodeGraphPanel": {
|
|
188
|
+
"resourceType": "Grafana::Panel::nodeGraph",
|
|
189
|
+
"kind": "resource",
|
|
190
|
+
"lexicon": "grafana"
|
|
191
|
+
},
|
|
192
|
+
"NotificationPolicy": {
|
|
193
|
+
"resourceType": "Grafana::NotificationPolicy",
|
|
194
|
+
"kind": "resource",
|
|
195
|
+
"lexicon": "grafana"
|
|
196
|
+
},
|
|
197
|
+
"NotificationTemplate": {
|
|
198
|
+
"resourceType": "Grafana::NotificationTemplate",
|
|
199
|
+
"kind": "resource",
|
|
200
|
+
"lexicon": "grafana"
|
|
201
|
+
},
|
|
202
|
+
"PieChartPanel": {
|
|
203
|
+
"resourceType": "Grafana::Panel::piechart",
|
|
204
|
+
"kind": "resource",
|
|
205
|
+
"lexicon": "grafana"
|
|
206
|
+
},
|
|
207
|
+
"PostgresQuery": {
|
|
208
|
+
"resourceType": "Grafana::Query::grafana-postgresql-datasource",
|
|
209
|
+
"kind": "resource",
|
|
210
|
+
"lexicon": "grafana"
|
|
211
|
+
},
|
|
57
212
|
"PromQuery": {
|
|
58
213
|
"resourceType": "Grafana::Query::prometheus",
|
|
59
214
|
"kind": "resource",
|
|
60
215
|
"lexicon": "grafana"
|
|
61
216
|
},
|
|
217
|
+
"PyroscopeQuery": {
|
|
218
|
+
"resourceType": "Grafana::Query::grafana-pyroscope-datasource",
|
|
219
|
+
"kind": "resource",
|
|
220
|
+
"lexicon": "grafana"
|
|
221
|
+
},
|
|
62
222
|
"QueryVariable": {
|
|
63
223
|
"resourceType": "Grafana::Variable::query",
|
|
64
224
|
"kind": "resource",
|
|
65
225
|
"lexicon": "grafana"
|
|
66
226
|
},
|
|
227
|
+
"ReduceExpression": {
|
|
228
|
+
"resourceType": "Grafana::Expression::reduce",
|
|
229
|
+
"kind": "resource",
|
|
230
|
+
"lexicon": "grafana"
|
|
231
|
+
},
|
|
232
|
+
"ResampleExpression": {
|
|
233
|
+
"resourceType": "Grafana::Expression::resample",
|
|
234
|
+
"kind": "resource",
|
|
235
|
+
"lexicon": "grafana"
|
|
236
|
+
},
|
|
67
237
|
"Row": {
|
|
68
238
|
"resourceType": "Grafana::Row",
|
|
69
239
|
"kind": "resource",
|
|
70
240
|
"lexicon": "grafana"
|
|
71
241
|
},
|
|
242
|
+
"SqlExpression": {
|
|
243
|
+
"resourceType": "Grafana::Expression::sql",
|
|
244
|
+
"kind": "resource",
|
|
245
|
+
"lexicon": "grafana"
|
|
246
|
+
},
|
|
247
|
+
"StateTimelinePanel": {
|
|
248
|
+
"resourceType": "Grafana::Panel::state-timeline",
|
|
249
|
+
"kind": "resource",
|
|
250
|
+
"lexicon": "grafana"
|
|
251
|
+
},
|
|
72
252
|
"StatPanel": {
|
|
73
253
|
"resourceType": "Grafana::Panel::stat",
|
|
74
254
|
"kind": "resource",
|
|
75
255
|
"lexicon": "grafana"
|
|
76
256
|
},
|
|
257
|
+
"StatusHistoryPanel": {
|
|
258
|
+
"resourceType": "Grafana::Panel::status-history",
|
|
259
|
+
"kind": "resource",
|
|
260
|
+
"lexicon": "grafana"
|
|
261
|
+
},
|
|
262
|
+
"SwitchVariable": {
|
|
263
|
+
"resourceType": "Grafana::Variable::switch",
|
|
264
|
+
"kind": "resource",
|
|
265
|
+
"lexicon": "grafana"
|
|
266
|
+
},
|
|
77
267
|
"TablePanel": {
|
|
78
268
|
"resourceType": "Grafana::Panel::table",
|
|
79
269
|
"kind": "resource",
|
|
@@ -94,6 +284,11 @@
|
|
|
94
284
|
"kind": "resource",
|
|
95
285
|
"lexicon": "grafana"
|
|
96
286
|
},
|
|
287
|
+
"ThresholdExpression": {
|
|
288
|
+
"resourceType": "Grafana::Expression::threshold",
|
|
289
|
+
"kind": "resource",
|
|
290
|
+
"lexicon": "grafana"
|
|
291
|
+
},
|
|
97
292
|
"TimeSeriesPanel": {
|
|
98
293
|
"resourceType": "Grafana::Panel::timeseries",
|
|
99
294
|
"kind": "resource",
|
|
@@ -103,5 +298,15 @@
|
|
|
103
298
|
"resourceType": "Grafana::Panel::traces",
|
|
104
299
|
"kind": "resource",
|
|
105
300
|
"lexicon": "grafana"
|
|
301
|
+
},
|
|
302
|
+
"TrendPanel": {
|
|
303
|
+
"resourceType": "Grafana::Panel::trend",
|
|
304
|
+
"kind": "resource",
|
|
305
|
+
"lexicon": "grafana"
|
|
306
|
+
},
|
|
307
|
+
"XYChartPanel": {
|
|
308
|
+
"resourceType": "Grafana::Panel::xychart",
|
|
309
|
+
"kind": "resource",
|
|
310
|
+
"lexicon": "grafana"
|
|
106
311
|
}
|
|
107
312
|
}
|