Compare commits

..

216 Commits

Author SHA1 Message Date
Isabel Matwawana
3f1b4b8c08 [v9.4.x] update minimum supported version for MySQL (#92409)
* update minimum supported version for MySQL (#92356)

(cherry picked from commit 22ad1cc16f)

* Did a yarn install

* Fixed codespell errors

* Trigger CI

* Update docs/sources/release-notes/release-notes-8-2-0.md

---------

Co-authored-by: Irene Rodriguez <irene.rodriguez@grafana.com>
2024-08-29 12:24:08 +02:00
grafana-delivery-bot[bot]
2fd032b4cd [v9.4.x] Docs: Create the Azure AD application section has outdated information. (#87030)
Docs: Create the Azure AD application section has outdated information. (#71498)

Update index.md

(cherry picked from commit ccd2bff8b0)

Co-authored-by: Dai Nguyen <88277570+ej25a@users.noreply.github.com>
2024-04-29 10:31:55 +01:00
Gilles De Mey
3f6f95f6fa [v9.4.x] Alerting: Fix Graphite subqueries (#80969)
Alerting: Fix Graphite subqueries (#80744)

(cherry picked from commit 8a4bd85efd)
2024-01-22 13:40:54 +02:00
Alexander Weaver
afba981303 [v9.4.x] Annotations: Split cleanup into separate queries and deletes to avoid deadlocks on MySQL (#80683)
* Annotations: Split cleanup into separate queries and deletes to avoid deadlocks on MySQL (#80329)

* Split subquery when cleaning annotations

* update comment

* Raise batch size, now that we pay attention to it

* Iterate in batches

* Separate cancellable batch implementation to allow for multi-statement callbacks, add overload for single-statement use

* Use split-out utility in outer batching loop so it respects context cancellation

* guard against empty queries

* Use SQL parameters

* Use same approach for tags

* drop unused function

* Work around parameter limit on sqlite for large batches

* Bulk insert test data in DB

* Refactor test to customise test data creation

* Add test for catching SQLITE_MAX_VARIABLE_NUMBER limit

* Turn annotation cleanup test to integration tests

* lint

---------

Co-authored-by: Sofia Papagiannaki <1632407+papagian@users.noreply.github.com>
(cherry picked from commit 81c45bfe44)

* Revert value and logs per backport

* empty commit to kick actions
2024-01-17 12:08:19 -06:00
Ricky Whitaker
b4cf3493ed [9.4.x] Backport .github/workflows/pr-commands.yml to use github app (#80754)
* Backporting .github/workflows/pr-commands.yml to use github app

* updating enterprise-pr-check.yml workflow to use token
2024-01-17 11:35:52 -06:00
Sonia Aguilar
2c4f4f8b08 Alerting: Fix silences removing labels pressing enter (#79623)
* Fix Silences removing labels when user press enter in duration input

* trigger CI
2023-12-19 16:06:55 +01:00
Sonia Aguilar
4f5264353e [v9.4.x] Alerting: Fix for data source filter on cloud rules. (#79327) (#79353)
Alerting: Fix for data source filter on cloud rules. (#79327)

* fix data source filter not worling for cloud rules

* Add test

(cherry picked from commit e6f2de51a3)
2023-12-11 21:26:06 +01:00
gotjosh
1362a5a592 [v9.4.x] Alerting: Attempt to retry retryable errors (#79180)
Alerting: Attempt to retry retryable errors (#79161)

* Alerting: Attempt to retry retryable errors

Retrying has been broken for a good while now (at least since version 9.4) - this change attempts to re-introduce them in their simplest and safest form possible.

I first introduced #79095 to make sure we don't disrupt or put additional load on our customer's data sources with this change in a patch release. Paired with this change, retries can now work as expected.

There's two small differences between how retries work now and how they used to work in legacy alerting.

Retries only occur for valid alert definitions - if we suspect that that error comes from a malformed alert definition we skip retrying.
We have added a constant backoff of 1s in between retries.

---------


(cherry picked from commit c631261681)

Signed-off-by: gotjosh <josue.abreu@gmail.com>
2023-12-06 21:33:44 +00:00
gotjosh
d0c178499c [v9.4.x] Unified Alerting: Set to 1 by default (#79108)
Unified Alerting: Set `max_attempts` to 1 by default (#79095)

* Unified Alerting: Set `max_attempts` to 1 by default

The retry logic for unified alerting has been broken as far as v9.4.x, rather than fixing it in one go and causing a headache to our users with rules putting extra load on their datasources - I think a better approach is to simply set 1 as a default and then let our users change it.

I see two cons with this approach:

- Configuration for legacy to unified alerting cannot be ported over automatically, users will have to manually set `max_attempts` to 3 when migrating.
- Users expecting to get any sort of retrying (as with legacy alerting) will not have it out of the box and will have to manually edit the configuration.

Signed-off-by: gotjosh <josue.abreu@gmail.com>
---------

Signed-off-by: gotjosh <josue.abreu@gmail.com>
(cherry picked from commit 0c9356a3c7)
2023-12-05 20:14:01 +00:00
Alexander Zobnin
0cc6d80d52 [v9.4.x] RBAC: Fix permissions for dashboard import (#79060)
RBAC: Fix permissions for dashboard import (#78891)

(cherry picked from commit 8e01932166)
2023-12-05 11:41:09 +01:00
gotjosh
779214437e [v9.4.x] Alerting: Only warm alert state cache if execute_alerts=true (#78942)
Alerting: Only warm alert state cache if execute_alerts=true. (#78895)

* Alerting: Only warm alert state cache if execute_alerts=true.

If the Grafana instance is not executing alerts, then Warm()-ing the state
manager is wasteful and could lead to misleading rule status queries, as the
status returned will be always based on the state loaded from the database at
startup, and not the most recent evaluation state.

* Move Warm() down to shared conditional.

(cherry picked from commit 520c927931)

Co-authored-by: Steve Simpson <steve.simpson@grafana.com>
2023-12-01 11:06:23 +00:00
Gilles De Mey
756861c1ed [v9.4.x] Alerting: Fixes combination of multiple predicates for rule search (#78913)
Alerting: Fixes combination of multiple predicates for rule search (#78910)

(cherry picked from commit 7ccdea6f67)
2023-11-30 18:06:49 +02:00
grafana-delivery-bot[bot]
0152b71e38 [v9.4.x] Alerting: Respect "For" Duration when NoData set to Alerting (#78898)
Alerting: Respect "For" Duration for NoData alerts (#65574)

* Alerting: Respect "For" Duration for NoData alerts

This change modifies `resultNoData` to be more inline with the logic of the other state handlers.

The main effects of this are:

1) NoData states with NoDataState config set to Alerting will respect "For" duration.
2) Prevents zero value in StartsAt and EndsAt for alerts that have only even been in normal state. This includes state transitions from NoDataState=OK and ExecErrState=OK.
3) Better state transition logging.

(cherry picked from commit b9dc04139a)

Co-authored-by: Matthew Jacobson <matthew.jacobson@grafana.com>
2023-11-30 12:24:58 +00:00
grafana-delivery-bot[bot]
34a5d7b399 [v9.4.x] fix: ha_peer to ha_peers (#78395)
fix: ha_peer to ha_peers (#75724)

(cherry picked from commit b3bf38ad68)

Co-authored-by: Arkadip Bhattacharya <in2arkadipb13@gmail.com>
2023-11-27 17:24:06 +02:00
Jack Baldry
0c01dbbd73 Add .codespellignore and fixing spelling errors (#78630)
Signed-off-by: Jack Baldry <jack.baldry@grafana.com>
2023-11-24 14:57:43 +00:00
Jean-Philippe Quéméner
48d96b03d6 fix: proper handling for queries with multiple conditions (#78499) 2023-11-21 20:12:16 +01:00
Gilles De Mey
020b1adf79 UI: Fix tab href race condition (#78458)
prevent tab clicking from activating the anchor's href

This prevents a very rare race condition when switching tabs very fast or when switching between tabs that update shortly after initial render.
2023-11-21 14:01:29 +02:00
Jean-Philippe Quéméner
670291e8a8 [v9.4.x] fix(alerting): fallback to dashboard to get the full targets PART5 (#78406) 2023-11-20 18:48:15 +01:00
Jean-Philippe Quéméner
7299e24f6e [v9.4.x] fix(alerting): fallback to dashboard to get the full targets PART4 (#78277) 2023-11-16 15:43:22 +01:00
Jean-Philippe Quéméner
974850e81a [v9.4.x] fix(alerting): fallback to dashboard to get the full targets PART 3 (#78240)
[v9.4.x] fix(alerting): fallback to dashboard to get the full targets PART3
2023-11-16 10:37:35 +01:00
Jean-Philippe Quéméner
d5bdc3e90d [v9.4.x] fix(alerting): fallback to dashboard to get the full targets… (#77779)
[v9.4.x] fix(alerting): fallback to dashboard to get the full targets PART2
2023-11-07 12:07:21 +01:00
Jean-Philippe Quéméner
bf2e034e49 [v9.4.x] fix(alerting): fallback to dashboard to get the full targets (#77693)
* [v9.4.x] fix(alerting): fallback to dashboard to get the full targets

* fix unit test

* fix more tests

* fix go lint
2023-11-06 14:06:59 +01:00
Matthew Jacobson
087cf5a877 [v9.4.x] Alerting: During legacy migration do not create one silence per rule (#77642)
* Alerting: During legacy migration do not create one silence per rule

During legacy migration every migrated rule is given a label rule_uid=<uid>.
This is used to silence migrated alerts if they were:

- Paused in legacy alerting.
- Had Error state set to keep last state.
- Had NoData state set to keep last state.

This can potentially create a large amount of silences and a high cardinality
label. Both of these scenarios have poor outcomes for CPU load and latency in
unified alerting.

Instead, this change opts to create one or more of three labels on each
migrated alert rule as well as three silence rules:

- migration_paused = true
- migration_keep_last_state_error = true
- migration_keep_last_state_nodata = true

 This will drastically reduce the number of created silence rules in most cases
 as well as not create the potentially high cardinalty label `rule_uid`.
2023-11-03 15:12:52 -04:00
grafana-delivery-bot[bot]
a6610343c9 [v9.4.x] Alerting: Fix state manager to not keep datasource_uid and ref_id labels in state after Error (#77392)
* Alerting: Fix state manager to not keep datasource_uid and ref_id labels in state after Error (#72216)

(cherry picked from commit 78fc3bcdf4)

* user QueryError

---------

Co-authored-by: Yuri Tseretyan <yuriy.tseretyan@grafana.com>
2023-11-03 12:05:36 -04:00
Kevin Minehart
4ff3b3e9b8 [v9.4.x] CI: Fix race condition when building docker on main (#77507)
CI: Fix race condition when building docker on main (#77504)

* build docker after packages are updated

* use my branch for main pipelines for testing

* use my branch for main pipelines for testing

* use main instead now

* formatting

(cherry picked from commit f6d3238505)
2023-11-01 18:54:24 +02:00
Kevin Minehart
2972ee8a22 [v9.4.x] CI: Update RGM steps to use the artifacts command (#77474)
CI: Update RGM steps to use the artifacts command (#77470)

* update rgm steps to use artifacts subcmd

* format-drone

* make drone

(cherry picked from commit 8a5d4c4c6e)
2023-10-31 15:40:17 -07:00
Ricky Whitaker
5730aa95bb [v9.4.x] Security Patch CI: Update to newest pr-patch-check.yml. (#77170) 2023-10-25 14:52:36 -05:00
Guilherme Caulada
0f5b0489bb [v9.4.x] CI: Rename scripts that build artifacts to use _build_ (#77015)
CI: Rename scripts that build artifacts to use _build_ (#77005)

Rename scripts that build artifacts to use _build_

(cherry picked from commit 442e533803)
2023-10-24 03:04:53 +03:00
Guilherme Caulada
2b54a169b2 [v9.4.x] CI: Update CI/CD tooling and pipelines from main (#76881)
* CI: Update CI/CD tooling and pipelines from main (#76814)

* CI: Update CI/CD tooling and pipelines from main

* Update Makefile

* Comment out validate_openapi_spec_step

* Update broken frontend tests

* Fix validate-npm-packages regex to work without suffix

* Fix cypress image version

(cherry picked from commit 03ecb1db39)

* Fix path for ./pkg/kindsys/report.go on Makefile

* Re-add ./pkg/cmd/grafana-cli/runner to make gen-go
2023-10-20 12:19:18 -03:00
Dimitris Sotirakis
6365037e69 [v9.4.x] CI: Remove 0.0.0-test tag event (#76666)
CI: Remove `0.0.0-test` tag event (#76662)

Remove 0.0.0-test tag event

(cherry picked from commit faa22b8f20)

# Conflicts:
#	.drone.yml
#	scripts/drone/pipelines/build.star
#	scripts/drone/steps/lib.star
2023-10-17 09:18:55 +01:00
grafana-delivery-bot[bot]
58b38800a9 [v9.4.x] Changelog: Updated changelog for 9.4.17 (#76454)
Changelog: Updated changelog for 9.4.17 (#76453)

Co-authored-by: grafanabot <bot@grafana.com>
(cherry picked from commit cfc33c12d1)

Co-authored-by: grafana-delivery-bot[bot] <132647405+grafana-delivery-bot[bot]@users.noreply.github.com>
2023-10-12 16:24:43 +03:00
Horst Gutmann
45813b1d3b [v9.4.x] Changelog: Updated changelog for 9.4.17 (#76412)
Changelog: Updated changelog for 9.4.17 (#76409)

Co-authored-by: grafanabot <bot@grafana.com>
(cherry picked from commit a9f7cb00e6)

Co-authored-by: grafana-delivery-bot[bot] <132647405+grafana-delivery-bot[bot]@users.noreply.github.com>
2023-10-12 07:21:32 -04:00
grafana-delivery-bot[bot]
a7a2cca9be Release: Bump version to 9.4.18 (#76413)
"Release: Updated versions in package to 9.4.18"

Co-authored-by: grafana-delivery-bot[bot] <132647405+grafana-delivery-bot[bot]@users.noreply.github.com>
2023-10-12 12:55:48 +03:00
Horst Gutmann
10e4fb4cf2 [v9.4.x] Chore: Upgrade Go to 1.20.10 (#76370)
Chore: Upgrade Go to 1.20.10 (#76355)

* [v10.1.x] Chore: Upgrade Go to 1.20.10

* Rebuild .drone.yml

(cherry picked from commit 4287686420)
2023-10-11 18:03:42 +03:00
Horst Gutmann
f6b68f9bf4 [v9.4.x] Building: Remove dependency to urw-fonts in RPM packages (#76223)
Building: Remove dependency to urw-fonts in RPM packages (#76198)

(cherry picked from commit 1355660313)
2023-10-10 09:51:52 +03:00
Ricky Whitaker
76b9390707 [v9.4.x] Adding .github/workflows/create-security-patch-from-security-mirror.yml (#75996)
Adding .github/workflows/create-security-patch-from-security-mirror.yml (#75850)

* Adding .github/workflows/create-security-patch-from-security-mirror.yml

* Added .github/workflows/create-security-patch-from-security-mirror.yml to CODEOWNERS

(cherry picked from commit 6842cc63ec)
2023-10-05 10:53:39 -05:00
grafana-delivery-bot[bot]
e9825f1769 [v9.4.x] [v10.1.x] Docs: Remove duplicate "Legend values" heading (#75891)
[v10.1.x] Docs: Remove duplicate "Legend values" heading (#75800)

Docs: Remove duplicate "Legend values" heading (#75692)

* Replaced legends shared content with text

* Copy and structuring edits

* Removed redundant link

* Prettier

---------

(cherry picked from commit 61b856c7dc)

Signed-off-by: Jack Baldry <jack.baldry@grafana.com>
Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
(cherry picked from commit c629e3b09c)

Co-authored-by: Jack Baldry <jack.baldry@grafana.com>
2023-10-03 10:26:43 -04:00
Jack Baldry
4d64abd286 Actually remove plugins docs from v9.4.x now that all the links are redirected to https://grafana.com/developers/ (#75612)
* Update `make docs` procedure

Signed-off-by: Jack Baldry <jack.baldry@grafana.com>

* Actually remove the plugins docs now that all the links are redirected to https://grafana.com/developers/

Signed-off-by: Jack Baldry <jack.baldry@grafana.com>

---------

Signed-off-by: Jack Baldry <jack.baldry@grafana.com>
2023-09-28 17:27:20 +01:00
Jack Baldry
0b51015dc9 fix links (#75524) (#75607)
Co-authored-by: brendamuir <100768211+brendamuir@users.noreply.github.com>
2023-09-28 09:06:03 +01:00
Jack Baldry
4cfad6b007 [v9.4.x] Remove plugins (#75582)
* Delete plugins files comprehensively

* Fix all links to "Sign a plugin" pages

Signed-off-by: Jack Baldry <jack.baldry@grafana.com>

* [publish_dashboards]

* Fix metadata links

Signed-off-by: Jack Baldry <jack.baldry@grafana.com>

* [publish-technical-documentation-next] Publish from grafana/agent:main/docs/sources

* Fix data-frames redirect

Signed-off-by: Jack Baldry <jack.baldry@grafana.com>

* add collapse shortcode (#15422)

* Add note about missing rewrites

Signed-off-by: Jack Baldry <jack.baldry@grafana.com>

* Fix all data-frames links

Signed-off-by: Jack Baldry <jack.baldry@grafana.com>

* Fix links to "plugins"

Signed-off-by: Jack Baldry <jack.baldry@grafana.com>

* Fix "plugin-sdk-go" links

Signed-off-by: Jack Baldry <jack.baldry@grafana.com>

* Fix backend links

Signed-off-by: Jack Baldry <jack.baldry@grafana.com>

* Fix "Add query editor help" links

Signed-off-by: Jack Baldry <jack.baldry@grafana.com>

* Fix some remaining links

Signed-off-by: Jack Baldry <jack.baldry@grafana.com>

* [publish_plugins]

* [publish-technical-documentation-release] Publish from grafana/grafana:v9.4.x/docs/sources

* Add missing redirects and fix a couple more links

Signed-off-by: Jack Baldry <jack.baldry@grafana.com>

---------

Signed-off-by: Jack Baldry <jack.baldry@grafana.com>
2023-09-27 18:23:14 +01:00
brendamuir
be49ccde9f fix links (#75524) 2023-09-27 14:22:02 +02:00
grafana-delivery-bot[bot]
a5a8208b2d Release: Bump version to 9.4.16 (#75050)
"Release: Updated versions in package to 9.4.16"

Co-authored-by: grafana-delivery-bot[bot] <132647405+grafana-delivery-bot[bot]@users.noreply.github.com>
2023-09-19 08:53:45 +03:00
Horst Gutmann
b6d733e755 [v9.4.x] Changelog: Updated changelog for 9.4.15 (#75051)
Changelog: Updated changelog for 9.4.15 (#75049)

Co-authored-by: grafanabot <bot@grafana.com>
(cherry picked from commit bc02197f06)

Co-authored-by: grafana-delivery-bot[bot] <132647405+grafana-delivery-bot[bot]@users.noreply.github.com>
2023-09-19 06:52:35 +01:00
Horst Gutmann
78ec819807 [v9.4.x] Chore: Upgrade Alpine base image to 3.18.3 (#74996)
Chore: Upgrade Alpine base image to 3.18.3 (#74984)

(cherry picked from commit 85abf2bebd)
2023-09-18 13:28:43 +03:00
Horst Gutmann
0ceb86a4c4 [v9.4.x] Chore: Upgrade Go to 1.20.8 (#74981)
Chore: Upgrade Go to 1.20.8 (#74978)

chore: Update to Go 1.20.8
(cherry picked from commit 39dbd98458)
2023-09-18 11:48:43 +03:00
Yuri Tseretyan
6d1747ff16 [v9.4.x] SSE: Fix DSNode to not panic when response has empty response (#74870)
Fix DSNode to not panic when response has empty response (#74866)
2023-09-13 15:17:07 -04:00
grafana-delivery-bot[bot]
d442068cdc [v9.4.x] Alerting docs: adds roll back warning to config grafana (#74828)
Alerting docs: adds roll back warning to config grafana (#74785)

(cherry picked from commit 38c3483594)

Co-authored-by: brendamuir <100768211+brendamuir@users.noreply.github.com>
2023-09-13 15:35:54 +03:00
Josh Hunt
a86847aff2 [v9.4.x] BrowseDashboards: Only remember the most recent expanded folder (#74812)
BrowseDashboards: Only remember the most recent expanded folder (#74617)

* BrowseDashboards: Only remember the most recent expanded folder

* set to null

* cleanup

* only clear removed folder if it was the most recently opened

* comments + variable

(cherry picked from commit 5cb7eb5884)
2023-09-13 10:55:53 +00:00
grafana-delivery-bot[bot]
ff961d322e [v9.4.x] Fix absolute aliases in contact points page (#74803)
Fix absolute aliases in contact points page (#74672)

Signed-off-by: Jack Baldry <jack.baldry@grafana.com>
(cherry picked from commit 5ff999bdae)

Co-authored-by: Jack Baldry <jack.baldry@grafana.com>
2023-09-13 10:40:22 +01:00
Dimitris Sotirakis
d868da883e [v9.4.x] Chore: Remove unused secret enterprise2-cdn-path - Nightlies: Push windows artifacts to GCS on main builds (#74789)
* Nightlies: Push windows artifacts to GCS on main builds (#74709)

* Push windows artifacts to gcs

* Lint starlark

* Sign drone

(cherry picked from commit 02f617a20d)

# Conflicts:
#	.drone.yml

* Chore: Remove unused secret `enterprise2-cdn-path` (#74741)

Remove unused secret

# Conflicts:
#	.drone.yml

(cherry picked from commit 49165d35ad)

# Conflicts:
#	.drone.yml
2023-09-13 10:19:24 +02:00
Dimitris Sotirakis
a55a38d191 [v9.4.x] Nightlies: Bring back windows installers for main builds (#74705)
Bring back windows installers for main builds (#74698)

(cherry picked from commit 36728dd671)

# Conflicts:
#	.drone.yml
2023-09-12 12:00:50 +03:00
Ieva
c37cebb26f [v9.4.x] Search: Improvements for starred dashboard search (#74662)
* fix merge conflicts

* fix test
2023-09-11 16:54:51 +03:00
ismail simsek
aa758499ea [v9.4.x] Prometheus: Handle the response with different field key order (#74623)
Prometheus: Handle the response with different field key order (#74567)

* Handle the response with different field key order

* More unit tests to cover edge cases

* Cover more edge cases

* make it simpler

* Better test inputs

(cherry picked from commit 3107459e57)
2023-09-11 13:41:29 +02:00
Yuri Tseretyan
82ac2432d4 SSE: DSNode to update result with names to make each value identifiable by labels (only Graphite and TestData) (#74615)
SSE: DSNode to update result with names to make each value identifiable by labels (only Graphite and TestData) (#73642)

* SSE: DSNode to update result with names to make each value identifiable by labels (only Graphite and TestData) (#71246)

* introduce a function checkIfSeriesNeedToBeFixed to scan all value fields in the response and provide a function that updates Series so they can be uniquely identifiable. Only Graphite and TestData are checked.

* update `DSNode.Execute` to run this function and provide it to WideToMany
* update WideToMany to run the fix function if it is not nil
2023-09-08 15:04:24 -04:00
grafana-delivery-bot[bot]
0f6c2b6954 [v9.4.x] SQL Datasources: Fix variable throwing error if query returns no data (#74609)
SQL Datasources: Fix variable throwing error if query returns no data (#65937)

* Fix SQL query variable throwing error if query returns no data

* Tests to verify that metricFindQuery returns properly and doesn't throw error

* Fix all codepaths that might throw errors because of undefined backendSrv response

(cherry picked from commit 02a8bc76d2)

Co-authored-by: Victor Marin <36818606+mdvictor@users.noreply.github.com>
2023-09-08 18:06:45 +03:00
Julien Duchesne
56a1bf85ea [v9.4.x] CI: Get Github Token and Docker username/password from Vault (#74570)
CI: Get Github Token and Docker username/password from Vault (#74555)

CI: Get Docker username/password from Vault
Not Drone secrets

(cherry picked from commit 566215c22c)
2023-09-08 08:31:35 +03:00
Horst Gutmann
b887f7eca6 [v9.4.x] CI: Run auto-milestone workflow also on reopened pull-requests (#74524)
CI: Run auto-milestone workflow also on reopened pull-requests (#74390)

(cherry picked from commit 94c9bee181)
2023-09-07 14:40:23 +03:00
grafana-delivery-bot[bot]
cc532753be [v9.4.x] Documentation linting on library_element docs (#74481)
Documentation linting on library_element docs (#74407)

* vale lint documentation changes

* run prettier

---------

Co-authored-by: unknown <antonio.caleromerello@grafana.com>
(cherry picked from commit b0715816d8)

Co-authored-by: David Allen <david.allen@grafana.com>
2023-09-06 22:30:41 +02:00
Christopher Moyer
0eb06914bd Docs: updates relref (#74413)
* updates relref

* Update docs/sources/setup-grafana/installation/redhat-rhel-fedora/index.md

Co-authored-by: Jack Baldry <jack.baldry@grafana.com>

---------

Co-authored-by: Jack Baldry <jack.baldry@grafana.com>
2023-09-06 08:49:37 -05:00
Horst Gutmann
8562a9732c [v9.4.x] Changelog: Updated changelog for 9.4.14 (#74369)
Changelog: Updated changelog for 9.4.14 (#74367)

Co-authored-by: grafanabot <bot@grafana.com>
(cherry picked from commit c8c9b6b767)

Co-authored-by: grafana-delivery-bot[bot] <132647405+grafana-delivery-bot[bot]@users.noreply.github.com>
2023-09-05 15:11:22 +03:00
grafana-delivery-bot[bot]
7911bfe2d0 Release: Bump version to 9.4.15 (#74370)
"Release: Updated versions in package to 9.4.15"

Co-authored-by: grafana-delivery-bot[bot] <132647405+grafana-delivery-bot[bot]@users.noreply.github.com>
2023-09-05 14:18:43 +03:00
Gabriel MABILLE
49d3cf745f [v9.4.x] LDAP: Fix user disabling (#74318)
* [LDAP] Disable removed users on login (#74016)

* manual backport of #74016 on legacy code

* LDAP: Fix active sync with large quantities of users (#73834)

* Fix authenticate user test
2023-09-04 16:14:20 +02:00
grafana-delivery-bot[bot]
1e00f2e0ab [v9.4.x] Docs: Fix broken link (#74185)
Docs: Fix broken link (#74141)

* Replaced partial URL with relref

* Changed link path

Co-authored-by: Jack Baldry <jack.baldry@grafana.com>

---------

Co-authored-by: Jack Baldry <jack.baldry@grafana.com>
(cherry picked from commit a45d292bf6)

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
2023-08-31 13:29:46 -04:00
Jack Baldry
ac29b6662d [v9.4.x] Update docs/shared shortcode usage to use keyword argument interface (#73765)
* Update all use of docs/shared in Grafana to use keyword arguments

Signed-off-by: Jack Baldry <jack.baldry@grafana.com>

* Add version inference to remaining Grafana docs/shared usage

Signed-off-by: Jack Baldry <jack.baldry@grafana.com>

---------

Signed-off-by: Jack Baldry <jack.baldry@grafana.com>
2023-08-31 11:06:43 +01:00
grafana-delivery-bot[bot]
fa6ddc2fba [v9.4.x] Update make docs procedure (#74158)
Update `make docs` procedure (#74152)

Co-authored-by: grafanabot <bot@grafana.com>
(cherry picked from commit 485f07cb7d)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-08-31 10:20:55 +01:00
grafana-delivery-bot[bot]
e04c22c3b7 [v9.4.x] Docker: Add musl as a ubuntu dependency (#74130)
Docker: Add musl as a ubuntu dependency (#74127)

Add musl as a ubuntu dependency

(cherry picked from commit 364ca3daa0)

Co-authored-by: Kevin Minehart <kmineh0151@gmail.com>
2023-08-30 22:02:54 +03:00
grafana-delivery-bot[bot]
b0e2eae439 [v9.4.x] Add LICENSE file to generated Docker images (#74099)
Add LICENSE file to generated Docker images (#74082)

(cherry picked from commit 6277c04caf)

Co-authored-by: Horst Gutmann <horst.gutmann@grafana.com>
2023-08-30 14:37:35 +03:00
Dimitris Sotirakis
01466f0fd9 [v9.4.x] CI: Mount /root/.docker/ dir in authenticate-gcr step (#74076)
CI: Mount /root/.docker/ dir in authenticate-gcr step  (#73977)

Mount /root/.docker/ dir

(cherry picked from commit eea4adea29)

# Conflicts:
#	.drone.yml
2023-08-30 11:15:02 +03:00
Guilherme Caulada
b68e5715e8 [v9.4.x] CI: Use new release eng managed grafanacom api key (#74032)
CI: Use new release eng managed grafanacom api key (#74017)

Use new release eng managed grafanacom api key

(cherry picked from commit ab7e655737)
2023-08-29 12:07:39 -03:00
Dimitris Sotirakis
bd1c66f220 [v9.4.x] Security: Authenticate to GCR for trivy scans (#73926)
Security: Authenticate to GCR for trivy scans (#72658)

* Authenticate to GCR for trivy scans

# Conflicts:
#	.drone.yml

* verify-starlark

* Change secret

# Conflicts:
#	.drone.yml

(cherry picked from commit e100fc927e)

# Conflicts:
#	.drone.yml
#	scripts/drone/vault.star
2023-08-28 16:00:24 +03:00
Dimitris Sotirakis
9aeb1db384 [v9.4.x] CI: Update secrets for publishing steps (#73663)
CI: Update secrets for publishing steps (#73658)

Update secrets

(cherry picked from commit de118a3736)

# Conflicts:
#	.drone.yml
2023-08-23 11:41:49 +03:00
Horst Gutmann
d1485fed57 [v9.4.x] CI: Different secret for verification and do not ignore build failures (#73618)
CI: Different secret for verification and do not ignore build failures (#73613)

(cherry picked from commit 8fc3be6b5a)
2023-08-22 16:34:04 +03:00
grafana-delivery-bot[bot]
135c74bd95 [v9.4.x] Update make docs procedure (#73544)
Update `make docs` procedure (#73540)

Co-authored-by: grafanabot <bot@grafana.com>
(cherry picked from commit 88d3f27b6b)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-08-21 09:18:44 +01:00
grafana-delivery-bot[bot]
b347249fa9 [v9.4.x] CI: Improve error handling in gcloud copy operations (#73536)
CI: Improve error handling in gcloud copy operations (#73474)

(cherry picked from commit 220ea869be)

Co-authored-by: Horst Gutmann <horst.gutmann@grafana.com>
2023-08-21 09:26:20 +03:00
grafana-delivery-bot[bot]
56ad16ffc4 [v9.4.x] Sync-mirror GHA updates (#73508)
Sync-mirror GHA updates (#73504)

fixing sync-mirror run-name and altering concurrency to use branch name

(cherry picked from commit 4047cdb213)

Co-authored-by: Ricky Whitaker <ricky.whitaker@grafana.com>
2023-08-18 12:47:24 -05:00
Horst Gutmann
7165da76cb [v9.4.x] CI: Move npm token to Vault (#73457)
CI: Move npm token to Vault (#73407)

(cherry picked from commit c86a73c794)
2023-08-18 09:00:08 +03:00
grafana-delivery-bot[bot]
c583fc795e [v9.4.x] Docs: Update dashboards api create/update (#73417)
Docs: Update dashboards api create/update (#73345)

(cherry picked from commit bb3a2d31d7)

Co-authored-by: Ezequiel Victorero <ezequiel.victorero@grafana.com>
2023-08-17 12:35:58 -05:00
grafana-delivery-bot[bot]
d7ba054f30 [v9.4.x] Update make docs procedure (#73386)
Update `make docs` procedure (#73359)

Co-authored-by: grafanabot <bot@grafana.com>
(cherry picked from commit 355917e755)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-08-17 15:48:38 +01:00
Dimitris Sotirakis
67c5afb44b [v9.4.x] CI: Update grabpl to v3.0.41 (#73373) (#73376)
CI: Update `grabpl` to `v3.0.41` (#73373)

Update grabpl

(cherry picked from commit 3463dc8e48)

# Conflicts:
#	.drone.yml
2023-08-17 13:08:42 +03:00
grafana-delivery-bot[bot]
a9bae1ad62 [v9.4.x] Grafana versioning: Remove pre suffix from Grafana version (#73364)
Grafana versioning: Remove `pre` suffix from Grafana version (#73357)

* Remove pre suffix from version

* Fix tests

(cherry picked from commit 0aba319ea0)

Co-authored-by: Dimitris Sotirakis <dimitrios.sotirakis@grafana.com>
2023-08-17 11:29:10 +03:00
grafana-delivery-bot[bot]
e0806338ab [v9.4.x] docs: add default value workaround (#73001)
docs: add default value workaround (#72545)

* Update _index.md

Fixes #https://github.com/grafana/support-escalations/issues/6376

Variables : Added Default values

* Update docs/sources/dashboards/variables/_index.md

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>

* Ran prettier to resolve build errors

---------

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
Co-authored-by: Isabel Matwawana <isabel.matwawana@grafana.com>
Co-authored-by: Jack Baldry <jack.baldry@grafana.com>
(cherry picked from commit 54f0de313f)

Co-authored-by: arunkg2787 <131352769+arunkg2787@users.noreply.github.com>
2023-08-07 12:49:12 -04:00
Christopher Moyer
257a489d38 [Docs 9.4x] - Manual backport, Clarify necessary rediss scheme for TLS with redis caching (#72122) (#72647)
Clarify necessary rediss scheme for TLS with redis caching (#72122)

Update index.md

To enable TLS with Redis you must use the `rediss` scheme, not the `redis` scheme. This is documented here: https://www.iana.org/assignments/uri-schemes/prov/rediss

(cherry picked from commit e03303997a)

Co-authored-by: chrisharbro <102977229+chrisharbro@users.noreply.github.com>
2023-07-31 15:13:38 -05:00
Christopher Moyer
14ca449530 [Docs v9.4x] Manual backport - Update _index.md (#72068) (#72195)
* Update _index.md (#72068)

* Update _index.md

Edits to the "Set up image rendering" doc.

1. First section, "Set up Image Rendering," last paragraph:
"You can also render a PNG by clicking hovering..." -- I removed "clicking" from that sentence.

2. "Alerting and Render Limits" section, link for "concurrent_render_limit" takes you to the page but not the section. This seems to be the case for all section links on this "Configure Grafana" page. I'm not sure how to fix it but switched from a relative link to a full path to see if that would help.

3. "Install Grafana Image Renderer Plugin," the link goes to the plugin overview page instead of the installation page. I tried adding the full path to see if that would go to the installation tab.

4. "Configuration" section, the same as the second edit I made, the first link, "Grafana configuration file," goes to the page but not the section link. I switched the relative path to a full path to see if it would work.

5. "Security" section, the very last sentence has the same Grafana configuration page link that goes to the correct page but not the correct section, "Grafana configuration" for the renderer token section. Same as previous ones, I switched out the relative path for the full path.

6. "Start browser with additional arguments," the second link in the first paragraph that goes to Puppeteer list of Chromium flags went to a 404 page. I couldn't figure out where they had moved it so I found a different site with a list of default flags and used that link instead.

* corrects links

* updates links

* fixes anchor link

---------

Co-authored-by: Chris Moyer <chris.moyer@grafana.com>
(cherry picked from commit b88a321ad2)

* Apply suggestions from code review

---------

Co-authored-by: Eva <ebuchala@gmail.com>
2023-07-31 12:06:57 -07:00
Ieva
8aa4245fe4 [v9.4.x] Docs: remove references to groups_attribute_path for Okta and GitLab docs (#72591)
Docs: remove references to `groups_attribute_path` for Okta and GitLab docs (#72588)

remove references to groups_attribute_path for Okta and GitLab

(cherry picked from commit b96d6e2c8d)
2023-07-31 13:09:31 +02:00
Guilherme Caulada
abd2ccc250 [v9.4.x] CI: Update secret refs to vault ones; update downstream repo origin (#72547)
CI: Update secret refs to vault ones; update downstream repo origin (#72515)

Update secret refs to vault ones; update downstream repo origin

(cherry picked from commit 6669d0a704)

Co-authored-by: Kevin Minehart <kmineh0151@gmail.com>
2023-07-28 16:00:23 -03:00
Kevin Minehart
b8120d421d [v9.4.x] CI: Make RGM the main pipeline for prerelease (#72530)
CI: Make RGM the main pipeline for prerelease (#72295)

* Make RGM the main pipeline for prerelease

* Use grafana/grafana-build:dev-bd41660

* Use grafana/grafana-build:dev-fda506a

* Fix destination url

* Update vault secrets

* Move bucket path to environment

* Use grafana/grafana-build:dev-2f36afa

* Revert to grafana/grafana-build:main

* Add repo to rgm_main trigger

(cherry picked from commit 971f5f14be)

Co-authored-by: Guilherme Caulada <guilherme.caulada@grafana.com>
2023-07-28 12:31:10 -03:00
Kevin Minehart
4201e7faea [v9.4.x] CI: use base64 key in windows installer build step (#72452)
CI: use base64 key in windows installer build step (#72413)

use base64 key

(cherry picked from commit b019ef9a89)
2023-07-27 16:29:58 +03:00
Dimitris Sotirakis
9203d5b116 [v9.4.x] CI: Fix deb/rpm bug for linux package publishing (#72422)
CI: Fix `deb/rpm` bug for linux package publishing (#72336)

Fix deb/rpm

(cherry picked from commit c3ebd388e3)
(cherry picked from commit 4c9bdef98dcfb24d8d24dac8117c9d3feb921a06)

# Conflicts:
#	.drone.yml
(cherry picked from commit e3ec53b418)

# Conflicts:
#	.drone.yml
2023-07-27 09:58:24 +03:00
Kevin Minehart
d5d838eaa1 [v9.4.x] CI: use the base64 key in the windows installer steps (#72379)
CI: use the base64 key in the windows installer steps (#72372)

use the base64 key in the windows installer steps

(cherry picked from commit 0c2b2219bb)
2023-07-26 12:04:00 -03:00
grafana-delivery-bot[bot]
549387b831 [v9.4.x] Prometheus: Add present_over_time syntax highlighting (#72366)
Prometheus: Add present_over_time syntax highlighting (#72283)

add prometheus present_over_time syntax highlighting

to color present_over_time keyword for prometheus

(cherry picked from commit d96067985b)

Co-authored-by: stratomonitor <arnaud_lemaignen@yahoo.com>
2023-07-26 08:41:26 -05:00
Ieva
c8687a78ff [v9.4.x] Docs: update GitLab OAuth2 documentation (#72343)
* backport

* linting
2023-07-26 11:06:45 +00:00
Guilherme Caulada
f35d160b67 [v9.4.x] CI: Fix verify-prerelease-assets pipeline (#72230)
CI: Fix verify-prerelease-assets pipeline (#72226)

* Fix verify-prerelease-assets pipeline

* Comment out unused assets

(cherry picked from commit 142cbc2ec6)
2023-07-25 00:56:54 +03:00
Christopher Moyer
7e71245181 [Docs v9.4x]: Manual backport, adds link to HA docs Update _index.md (#71400) (#72136)
Update _index.md (#71400)

* Update _index.md

Added missing hyperlink for high availability and a small typo

* updates link

---------

Co-authored-by: Chris Moyer <chris.moyer@grafana.com>
(cherry picked from commit 4e50115d95)

Co-authored-by: Usman Ahmad <usman.ahmad@grafana.com>
2023-07-24 10:43:23 -04:00
Kevin Minehart
41c04aecbb [v9.4.x] CI: Run only Grafana builds on RGM for grafana/grafana (#72159)
* CI: Try setting the vault secret for 'grafana_api_key' (#71981)

* Try setting the vault secret

* Maybe?

* forgot .drone.yml

* CI: Use GCP keys in vault and not drone secrets (#72023)

* CI: Run only Grafana builds on RGM for grafana/grafana (#72144)

* Run only OSS builds on RGM for grafana/grafana

* Update script name

* Ignore windows step failure for RGM

---------

Co-authored-by: Guilherme Caulada <guilherme.caulada@grafana.com>
2023-07-21 18:27:36 -03:00
grafana-delivery-bot[bot]
e925841872 [v9.4.x] docs: fix broken link (#72154)
docs: fix broken link (#72114)

(cherry picked from commit 0589060041)

Co-authored-by: David Harris <david.harris@grafana.com>
2023-07-21 16:56:16 -04:00
grafana-delivery-bot[bot]
3c987bd8c4 [v9.4.x] Docs: adds mimir and oncall (#72047)
Docs: adds mimir and oncall (#72042)

adds mimir and oncall

(cherry picked from commit 46c49aa7ff)

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>
2023-07-20 12:09:58 -05:00
lwandz13
64307da9ea Docs: add alias to data sources index file 9.4 (#71985)
added features alias to front matter
2023-07-20 09:34:15 -05:00
grafana-delivery-bot[bot]
95a61e652a [v9.4.x] AuthNZ documentation revamp (#71967)
AuthNZ documentation revamp (#62581)

* init for base branch

* Add authnz code ownership

* Fix docs ownsership path

* docs revamp: Plan IAM strategy (#62582)

* Add planning page

* Add teams definition

* Expand on planning and benefits

* Add reasons to organize users

* Add description of User Teams

* Add Grafana organizations info

* Add a section between Teams and Orgs

* Add a section for external systems

* planning your role strategy

* Add service account documentation

* Add Auth Setup to index sidebar

* Address PR comments

* Add planning for API keys

* Add team and org sync

* Docs: role and permission section for planning docs (#64702)

* docs revamp: Service accounts (#63710)

* docs revamp: Add new documentation to sidebar index (#66104)

* docs revamp: synchronisation planning (#66409)

* Docs: api keys (#64803)

* Remove personal access tokens section

* Move auth integration planning page

* Remove auth folder

* Restore codeowners file

* reword and update info on user management and grouping

* Rename iam strategy page

* extend the section on teams and organizations

* Rename planning your IAM section

* Move to administration section

* Add definition for role sync

* Relocate planning

---------

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>
Co-authored-by: Ieva <ieva.vasiljeva@grafana.com>
(cherry picked from commit 63346674e6)

Co-authored-by: linoman <2051016+linoman@users.noreply.github.com>
2023-07-19 16:17:55 -05:00
Guilherme Caulada
32830edc60 [v9.4.x] CI: Allow RGM to create msi for multiple editions (#71892)
CI: Allow RGM to create msi for multiple editions (#71883)

* Allow RGM to create msi for multiple editions

* Remove suffix from build-windows-installer step

* Invert exit code on verify_release_pipeline

(cherry picked from commit 4c80bcf35f)
2023-07-19 13:35:16 -03:00
Isabel
97aabc8497 [v9.4.x] docs: add docker commands for enabling alpha layers (#71963)
docs: add docker commands for enabling alpha layers (#71897)

added docker commands for enabling alpha layers

(cherry picked from commit ef0de1af32)
2023-07-19 12:34:52 -04:00
Dimitris Sotirakis
c6634f3780 [v9.4.x] Bug: Compare semver digits for frontend packages config (#71906)
Bug: Compare `semver` digits for frontend packages config (#71829)

* Compare semver digits

* Fix lint

(cherry picked from commit 5f8ace33fb)

# Conflicts:
#	pkg/build/frontend/config_test.go
2023-07-19 10:21:47 +03:00
grafana-delivery-bot[bot]
da681e13f2 [v9.4.x] Update _index.md (#71796)
Update _index.md (#71792)

* Update _index.md

* makes prettier

---------

Co-authored-by: Chris Moyer <chris.moyer@grafana.com>
(cherry picked from commit 03c2efa2d6)

Co-authored-by: Melori Arellano <melori.arellano@grafana.com>
2023-07-18 14:29:37 -05:00
Guilherme Caulada
e3be6812ce [v9.4.x] CI: Add rgm compatible windows msi pipeline (#71857)
CI: Add rgm compatible windows msi pipeline (#71678)

* Add rgm compatible windows msi pipeline

* Fix dependencies and platform

* Fix missing arg comment

* Fix linting issues

* Try to fix version on file path

* Fix dependency on verify release pipeline

(cherry picked from commit 4caa773401)
2023-07-18 13:51:07 -03:00
linoman
0817676d9e [v9.4.x] Rework Okta OAuth2 (#71860)
Rework Okta OAuth2 (#71349)

* Rework Okta OAuth2

---------

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>
Co-authored-by: Ieva <ieva.vasiljeva@grafana.com>
(cherry picked from commit 130f142c7f)
2023-07-18 17:36:33 +02:00
grafana-delivery-bot[bot]
4333d651e1 [v9.4.x] docs: Update Transform Data (#71852)
docs: Update Transform Data (#71013)

* Update Transform Data :docs:

* Apply suggestions from code review Update Transform Data

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>

* Fix link

* Various suggestions

* Various suggestions

* Various suggestions

* Reset make file

* Add example for extract field

* Add example for field lookup

* Add example for histogram

* Update

* Update docs/sources/panels-visualizations/query-transform-data/transform-data/index.md

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>

* Update docs/sources/panels-visualizations/query-transform-data/transform-data/index.md

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>

* Update docs/sources/panels-visualizations/query-transform-data/transform-data/index.md

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>

* Update docs/sources/panels-visualizations/query-transform-data/transform-data/index.md

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>

* Update docs/sources/panels-visualizations/query-transform-data/transform-data/index.md

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>

* Update docs/sources/panels-visualizations/query-transform-data/transform-data/index.md

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>

* Update docs/sources/panels-visualizations/query-transform-data/transform-data/index.md

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>

* Update docs/sources/panels-visualizations/query-transform-data/transform-data/index.md

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>

* Update docs/sources/panels-visualizations/query-transform-data/transform-data/index.md

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>

* Update docs/sources/panels-visualizations/query-transform-data/transform-data/index.md

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>

* Update docs/sources/panels-visualizations/query-transform-data/transform-data/index.md

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>

---------

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
Co-authored-by: ludovio <ludovic.viaud@gmail.com>
(cherry picked from commit 679365960b)

Co-authored-by: Jara Suárez de Puga García <jara.suarezdepuga@grafana.com>
2023-07-18 10:37:46 -04:00
Guilherme Caulada
20f001649e [v9.4.x] CI: Removes enterprise specific pipelines and steps (#71775)
[WIP] CI: Removes enterprise specific pipelines and steps (#70815)

* Removes enterprise specific pipelines and steps (#123)

* Comment out enterprise related pipelines and steps

* Suppress unused variable warning

* Removes all edition arguments

* Remove leftover comments

* Remove redundant oss on pipelines and steps names

* Remove leftover unused variable

* Remove leftovers

* Remove pipeline dependencies

* Rename pipelines

* Fix starlark

---------

Co-authored-by: dsotirakis <dimitrios.sotirakis@grafana.com>
(cherry picked from commit 642a81ba75e79138246797302aba5c35575f030d)

* Add editions for static assets

(cherry picked from commit b13939b9af)

Co-authored-by: Dimitris Sotirakis <dimitrios.sotirakis@grafana.com>
2023-07-18 11:17:11 -03:00
linoman
c465fa856e [v9.4.x] Auth: update generic OAuth documentation (#71639)
* Auth: update generic OAuth documentation (#70330)

* update generic OAuth docs

* some more fixes and corrections

* update examples and sync sections

* fix a link

* linting

* formatting and adding more links to OAuth integrations

* add a section with config walkthrough

* fix link

* move examples to the end of the doc

* extend role mapping

* small improvements

* add a before you begin section, clean up steps, remove some text

* remove unnecessary section

* merge main 2

* OAuth -> OAuth2

* remove Centrify example because it's likely outdated

* add shared intro content

* indentation

* add refresh token to tasks, clean up more sections

* linting

* linting

* Apply suggestions from code review

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-security/configure-authentication/generic-oauth/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* indentation and small descriptions under headings

* add a table for config options

* clean up more sections

* rewrite email address section

* rewriting login and display name sections, plus adding line breaks

* clean up more sections

* update role mapping section

* indentation again

* update section names

* incorporates final edits

* Apply suggestions from code review

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* pr feedback

* Apply suggestions from code review

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* PR feedback: rewording

---------

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>
Co-authored-by: Chris Moyer <chris.moyer@grafana.com>
(cherry picked from commit 276c63a656)

* linting

---------

Co-authored-by: Ieva <ieva.vasiljeva@grafana.com>
2023-07-17 12:27:21 +00:00
grafana-delivery-bot[bot]
98d339bc12 [v9.4.x] Plugins: Only configure plugin proxy transport once (#71740)
Plugins: Only configure plugin proxy transport once (#71735)

only configure plugin proxy transport once

(cherry picked from commit b59ca7fb22)

Co-authored-by: Will Browne <wbrowne@users.noreply.github.com>
2023-07-17 14:54:03 +03:00
grafana-delivery-bot[bot]
55abd83948 [v9.4.x] CI: Re-enable milestone-check (#71721)
CI: Re-enable milestone-check (#71718)

This will hopefully resolve stuck PRs until we find a better way to
disable that check.

(cherry picked from commit 44b55a1ca6)

Co-authored-by: Horst Gutmann <horst.gutmann@grafana.com>
2023-07-17 12:18:00 +03:00
Dimitris Sotirakis
be7557306c [v9.4.x] CI: Fix broken env vars in publish-artifacts step (#71645)
CI: Fix broken env vars in publish-artifacts step (#71471)

Fix env vars

(cherry picked from commit 64d2ff03c80c807c03390f63ba1834c5605fc96d)

# Conflicts:
#	.drone.yml
(cherry picked from commit fd90737884)

# Conflicts:
#	.drone.yml
2023-07-17 11:53:31 +03:00
Horst Gutmann
5481d29428 [v9.4.x] Chore: Add auto-milestone workflow for pull-requests (#71709)
Chore: Add auto-milestone workflow for pull-requests (#71177)

This adds a new auto-milestone workflow that will set the milestone for
a PR when it is closed. This way, contributors no longer have to think
about milestone at all.

(cherry picked from commit 8ae92db53d)
2023-07-17 10:30:41 +02:00
linoman
093ea7cd47 [v9.4.x] Docs: reorder auth provider pages (#71642)
Docs: reorder auth provider pages (#70764)

* order auth provider pages

* add shorter menu titles

* linting

* update reference

* rename Grafana auth section to basic auth

(cherry picked from commit fc290281cb)

Co-authored-by: Ieva <ieva.vasiljeva@grafana.com>
2023-07-17 09:58:25 +02:00
linoman
3ecbd728b3 [v9.4.x] Auth: update GitHub OAuth documentation (#70459) (#71649)
Auth: update GitHub OAuth documentation (#70459)

* github oauth doc improvements

* add skip_org_role_sync to config for github provider

* update links and section headings

* update the docs based on the first PR

* update references

(cherry picked from commit cb695cef8e)

Co-authored-by: Ieva <ieva.vasiljeva@grafana.com>
2023-07-17 09:57:41 +02:00
grafana-delivery-bot[bot]
aff2783e68 [v9.4.x] Docs: Add reference to Grafana Cloud doc (#71666)
Docs: Add reference to Grafana Cloud doc (#71653)

Add reference to Grafana Cloud doc

(cherry picked from commit 6b40fe75f5)

Co-authored-by: Fabrizio <135109076+fabrizio-grafana@users.noreply.github.com>
2023-07-14 10:26:33 -05:00
Kevin Minehart
14484c46ad [v9.4.x] CI: Update and rename pr-patch-mirror-and-apply.yml to sync-mirror.yml (#71613)
CI: Update and rename pr-patch-mirror-and-apply.yml to sync-mirror.yml (#71608)

* CI: Update and rename pr-patch-mirror-and-apply.yml to sync-mirror.yml

* update CODEOWNERS

(cherry picked from commit 3afc20fae9)
2023-07-14 11:50:01 +01:00
Isabel
672a4d1590 [v9.4.x] docs: restructure dashboard annotations page (#71514)
* docs: restructure dashboard annotations page (#70208)

* restructured page, updated and removed images, replaced a paragraph with a procedure

* Clarify language

* Apply suggestions from code review

* removed native annotation language, added missing link, added text from UI

* fixed relref

* replaced relref with simple link

* updated links and link text in whats new for annotations updates

* fixed some grammar/wording and style issues

* Apply suggestions from code review

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* fix typo

Co-authored-by: Ezequiel Victorero <ezequiel.victorero@grafana.com>

* make link text more clear

* fix typo

---------

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>
Co-authored-by: Ezequiel Victorero <ezequiel.victorero@grafana.com>
(cherry picked from commit adc7f65453)

* fixed backport
2023-07-13 10:11:16 -04:00
Isabel
211bfd2f4d [v9.4.x] docs: add alphaPanels feature toggle information (#71508)
fix backport conflict
2023-07-13 01:25:32 +03:00
grafana-delivery-bot[bot]
89c1e4c35e [v9.4.x] CI: Rename the patch GHA workflows (#71475)
CI: Rename the patch GHA workflows (#71470)

* Rename the patch workflows

* Update codeowners

(cherry picked from commit 428f63518a)

Co-authored-by: Kevin Minehart <kmineh0151@gmail.com>
2023-07-12 10:35:17 -05:00
Christopher Moyer
c922a5f956 [DOC] Fix tracing links in explore/tracing (#71383) (#71392)
* [DOC] Fix tracing links in explore/tracing (#71383)

Fix tracing links

(cherry picked from commit 41def2e346)

* Update docs/sources/explore/trace-integration.md

Co-authored-by: Kim Nylander <104772500+knylander-grafana@users.noreply.github.com>

---------

Co-authored-by: Kim Nylander <104772500+knylander-grafana@users.noreply.github.com>
2023-07-11 11:57:41 -05:00
Emil Tullstedt
a4ab5bfaad [v9.4.x] CI: Provide a Drone promotion to build the build-container (#71350)
CI: Provide a Drone promotion to build the build-container (#71133)

(cherry picked from commit 7a9847e196)
2023-07-11 14:04:23 +02:00
grafana-delivery-bot[bot]
6480b50187 [v9.4.x] Docs: Fix broken links to play (#71294)
Docs: Fix broken links to play (#71112)

* fix broken links to play

* Update docs/sources/dashboards/variables/_index.md

Co-authored-by: lwandz13 <126723338+lwandz13@users.noreply.github.com>

---------

Co-authored-by: lwandz13 <126723338+lwandz13@users.noreply.github.com>
(cherry picked from commit 69d8e3d8dc)

Co-authored-by: matt abrams <37156449+zuchka@users.noreply.github.com>
2023-07-10 14:47:47 -04:00
grafana-delivery-bot[bot]
6ab231d61d [v9.4.x] Prometheus: Version detect bug (#71242)
Prometheus: Version detect bug (#71198)

* remove redundant request copy in backend, add more versions to semver lists

(cherry picked from commit 7dc071f46b)

Co-authored-by: Galen Kistler <109082771+gtk-grafana@users.noreply.github.com>
2023-07-07 14:21:31 -05:00
Kevin Minehart
19ea031bbd [v9.4.x] CI: Add GPG keys to rgm, don't clone RGM just use the docker image (#71231)
* CI: Add rgm to drone (#66991)

* add drone stub that build grafana using 'grafana/build' (dagger)

---------

Co-authored-by: Ricky Whitaker <ricky.whitaker@grafana.com>
(cherry picked from commit 768efe9748)

* Add dagger token to rgm builds (#68651)

(cherry picked from commit a870b227db)

* CI: Add GPG keys to rgm, don't clone RGM just use the docker image (#71143)

* Add GPG keys to rgm, dont' clone RGM just use the docker image

(cherry picked from commit d5a4c81fa1)
2023-07-07 20:23:39 +03:00
Christopher Moyer
f09edce739 Docs: update the word "integration" in Okta config (#71181) (#71210)
(cherry picked from commit ac78146091)

Co-authored-by: Mitch Seaman <mjseaman@users.noreply.github.com>
2023-07-07 09:39:49 -05:00
grafana-delivery-bot[bot]
fe5305ffeb [v9.4.x] InfluxDB: Interpolate retention policies (#71202)
InfluxDB: Interpolate retention policies (#69202)

Interpolate retention policies

(cherry picked from commit f610e37aec)

Co-authored-by: ismail simsek <ismailsimsek09@gmail.com>
2023-07-07 15:14:24 +02:00
grafana-delivery-bot[bot]
fa72114b45 [v9.4.x] Docs: Updates Grafana alerting link text on Panel Editor Overview page (#71195)
Docs: Updates Grafana alerting link text on Panel Editor Overview page (#71146)

* Updates Grafana alerting link text on panel editor overview page

* fixed wording of link text

---------

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
(cherry picked from commit 217265baee)

Co-authored-by: Leanna Shippy <11079957+lshippy@users.noreply.github.com>
2023-07-07 08:24:55 -04:00
grafana-delivery-bot[bot]
51b8889874 [v9.4.x] Added security patch delivery workflows (#71147)
Added security patch delivery workflows (#71101)

* adding security patch workflows

* adding grafana-delivery as codeowners for new pr-security-check workflows

* adding release branch triggers to PR security patch github action

* joined security patching mirror and apply jobs

* remove temp files

(cherry picked from commit d88046d3d4)

Co-authored-by: Ricky Whitaker <ricky.whitaker@grafana.com>
2023-07-06 11:11:27 -05:00
grafana-delivery-bot[bot]
3e8916aa81 [v9.4.x] Docs: update heatmap panel options (#71095)
Docs: update heatmap panel options (#71058)

Added some heatmap panel configuration options which were missing from the docs

(cherry picked from commit bdf60d69de)

Co-authored-by: prenzlern <88067634+prenzlern@users.noreply.github.com>
2023-07-05 13:52:18 -04:00
grafana-delivery-bot[bot]
edba3a2467 [v9.4.x] standardize docs copyright (#70829)
standardize docs copyright (#70732)

(cherry picked from commit 3e3bcf510b)

Co-authored-by: Robby Milo <robbymilo@fastmail.com>
2023-06-28 09:47:10 -04:00
grafana-delivery-bot[bot]
8dcfb83de4 [v9.4.x] CI: Ignore .pr-body.txt file (#70806)
CI: Ignore .pr-body.txt file (#70798)

This file is used during the backporting process but should never be
committed.

(cherry picked from commit 2b10d31bac)

Co-authored-by: Horst Gutmann <horst.gutmann@grafana.com>
2023-06-28 12:22:35 +03:00
Dimitris Sotirakis
4486f323ec [v9.4.x] CI: Cleanup - Remove security related steps (#70793)
CI: Cleanup - Remove security related steps (#70788)

* Remove security related steps

* More cleanup

(cherry picked from commit 7f55ba9c6e)
2023-06-28 11:38:03 +03:00
grafana-delivery-bot[bot]
1d34f16a3f [v9.4.x] Update to docs - index.md (#70751)
Update to docs -  index.md (#70699)

Update index.md

Minor correction.

(cherry picked from commit b32cea7929)

Co-authored-by: marybelvargas <107340764+marybelvargas@users.noreply.github.com>
2023-06-27 17:01:03 -05:00
Horst Gutmann
db737d1d96 [v9.4.x] Docs: Add missing entries to changelog for 9.4.9 (#70744) 2023-06-27 14:33:23 +03:00
grafana-delivery-bot[bot]
47e4a2f886 [v9.4.x] docs: fix broken links in Configure legend (#70709)
docs: fix broken links in Configure legend (#70696)

* fix broken links

* fix remaining broken links

(cherry picked from commit 2d261e7aef)

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
2023-06-26 13:54:38 -04:00
grafana-delivery-bot[bot]
fda6f03ec9 [v9.4.x] Docs: removes-yum (#70640)
Docs: removes-yum (#70634)

* removes-yum

* Update docs/sources/setup-grafana/installation/redhat-rhel-fedora/index.md

Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com>

* Update docs/sources/setup-grafana/installation/redhat-rhel-fedora/index.md

Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com>

* Update docs/sources/setup-grafana/installation/redhat-rhel-fedora/index.md

Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com>

* incorporates feedback

* adds GPG key step

* removes duplicate addrepo command

---------

Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com>
(cherry picked from commit 262af2c473)

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>
2023-06-23 14:35:22 -05:00
grafana-delivery-bot[bot]
b1d68dc18d [v9.4.x] Docs: removes references to Redhat, adds import GPG key step (#70630)
Docs: removes references to Redhat, adds import GPG key step (#70625)

removes references to Redhat, adds import GPG key step

(cherry picked from commit 06b1b6f552)

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>
2023-06-23 12:47:11 -05:00
grafana-delivery-bot[bot]
54e65f25b7 [v9.4.x] docs: clarifies that only OSS or Enterprise are installed (#70626)
docs: clarifies that only OSS or Enterprise are installed (#70619)

* clarifies that only OSS or Enterprise are installed,  not both

* Apply suggestions from code review

(cherry picked from commit f77a886f0e)

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>
2023-06-23 12:39:19 -05:00
grafana-delivery-bot[bot]
3db20d0149 [v9.4.x] formatting fix for line 72 (#70621)
formatting fix for line 72 (#70618)

(cherry picked from commit cbf4fe9d23)

Co-authored-by: Eve Meelan <81647476+Eve832@users.noreply.github.com>
2023-06-23 10:04:26 -07:00
grafana-delivery-bot[bot]
cb7a0bb612 [v9.4.x] Changelog: Updated changelog for 9.4.13 (#70596)
Changelog: Updated changelog for 9.4.13 (#70595)

Co-authored-by: grafanabot <bot@grafana.com>
(cherry picked from commit 15e134215a)

Co-authored-by: grafana-delivery-bot[bot] <132647405+grafana-delivery-bot[bot]@users.noreply.github.com>
2023-06-23 15:07:56 +03:00
Horst Gutmann
28005f8baa [v9.4.x] Auth: Fixed CVE-2023-3128 (#70579)
Auth: Fixed CVE-2023-3128 (#70571)

Fixed CVE-2023-3128

(cherry picked from commit 789ee2121e)

Co-authored-by: Misi <mgyongyosi@users.noreply.github.com>
2023-06-23 12:10:30 +02:00
Vardan Torosyan
1a333623cf [v9.4.x] Add and document option for enabling email lookup (#916)
Add and document option for enabling email lookup (#913)

* Docs: Document option for enabling email lookup

* Add the new config in the config files

* Apply suggestions from code review

Co-authored-by: Ieva <ieva.vasiljeva@grafana.com>

* Don't capitalize identity providers

* Apply suggestions from code review

Co-authored-by: Jo <joao.guerreiro@grafana.com>

* Apply suggestions from code review

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

---------

Co-authored-by: Ieva <ieva.vasiljeva@grafana.com>
Co-authored-by: Jo <joao.guerreiro@grafana.com>
Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>
(cherry picked from commit 8380bc7d6a79794cc260bf1c427e2b4e849adbf6)
2023-06-23 08:58:43 +02:00
Ieva
5829fdd399 Auth: Remove Email Lookup from oauth integrations 9.4 (#896)
backport https://github.com/grafana/grafana-private-mirror/pull/894 to 9.4.x
2023-06-23 08:58:42 +02:00
grafana-delivery-bot[bot]
1a07dc5db0 [v9.4.x] Changelog: Add CVE to 9.4.13 changelog (#70559)
Changelog: Add CVE to 9.4.13 changelog (#70558)

Add CVE to 9.4.13 changelog

(cherry picked from commit 69fc4e6bc0)

Co-authored-by: Guilherme Caulada <guilherme.caulada@grafana.com>
2023-06-22 18:17:55 -03:00
grafana-delivery-bot[bot]
f829ae71db Release: Bump version to 9.4.14 (#70557)
"Release: Updated versions in package to 9.4.14"

Co-authored-by: grafana-delivery-bot[bot] <132647405+grafana-delivery-bot[bot]@users.noreply.github.com>
2023-06-22 18:01:46 -03:00
Guilherme Caulada
43e78fa1a6 [v9.4.x] Changelog: Updated changelog for 9.4.13 (#70555)
* Changelog: Updated changelog for 9.4.13 (#70553)

Co-authored-by: grafanabot <bot@grafana.com>
(cherry picked from commit 58145908f4)

* Fix changelog conflict

---------

Co-authored-by: grafana-delivery-bot[bot] <132647405+grafana-delivery-bot[bot]@users.noreply.github.com>
2023-06-22 17:49:03 -03:00
grafana-delivery-bot[bot]
351450bfe0 [v9.4.x] Github Actions: Fix milestone GH action (#70497)
Github Actions: Fix milestone GH action (#70490)

* Remove secret from the caller action

* Inherit secrets for reusable actions

(cherry picked from commit 37db29db63)

Co-authored-by: Dimitris Sotirakis <dimitrios.sotirakis@grafana.com>
2023-06-22 19:17:40 +03:00
grafana-delivery-bot[bot]
69848e4349 [v9.4.x] docs: table panel: modified support section regarding alerts (#70532)
table panel: modified support section regarding alerts (#70421)

* modified support section

* Update docs/sources/panels-visualizations/visualizations/table/index.md

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>

* Update docs/sources/panels-visualizations/visualizations/table/index.md

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>

* fixing linting error

---------

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
Co-authored-by: Isabel Matwawana <isabel.matwawana@grafana.com>
(cherry picked from commit 8079c1456f)

Co-authored-by: tonypowa <45235678+tonypowa@users.noreply.github.com>
2023-06-22 11:34:13 -04:00
grafana-delivery-bot[bot]
28767f8a67 [v9.4.x] Docs: changes link text and adds link to the download page (#70507)
Docs: changes link text and adds link to the download page (#70477)

achanges link text and add link to the download page

(cherry picked from commit 5426d519c6)

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>
2023-06-22 06:55:17 -05:00
grafana-delivery-bot[bot]
ccbd6d0afb [v9.4.x] Docs: removes references to YUM (#70473)
Docs: removes references to YUM (#70471)

removes references to YUM

(cherry picked from commit ebdba3b359)

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>
2023-06-21 14:18:32 -05:00
Dimitris Sotirakis
b8ad4e0bb4 [v9.4.x] GitHub Apps: Replace grafanabot token with grafana-delivery-bot GitHub App (#70457)
* GitHub Apps: Replace `grafanabot` token with `grafana-delivery-bot` GitHub App (#70242)

* Update bump-version.yml

* Fix secret

* [REVERTME] Remove check

* Test without grafana-delivery-bot prefix

* Check if token exists

* Cleanup bump-version

* Update gh actions to use app key

(cherry picked from commit 15a85686c2)

# Conflicts:
#	.github/workflows/backport.yml
#	.github/workflows/bump-version.yml
#	.github/workflows/milestone.yml
#	.github/workflows/update-changelog.yml

* Bug: Fix `yaml` identation for github action yamls (#70445)

* Fix yaml identation

* Fix the rest of the yamls

(cherry picked from commit 31b9f9d235)
2023-06-21 16:32:58 +03:00
Grot (@grafanabot)
4add393ff0 [v9.4.x] docs: Fix bad markup in time series docs (#70388)
Fix bad markup in time series docs (#70352)

(cherry picked from commit d8a74ab1b7)

Co-authored-by: John Spurlock <john.spurlock@gmail.com>
2023-06-20 13:53:10 -04:00
Isabel
b640eb0c85 [v9.4.x] docs: Use "or" to convey that OS options are unique (#70353)
* Fix merge conflict
* Update relrefs

---------
Co-authored-by: Ursula Kallio <ursula.kallio@grafana.com>
2023-06-20 11:15:28 +02:00
Grot (@grafanabot)
ed6169688e [v9.4.x] Docs: List packages together, and fix or add menuTitles. (#70341)
Docs: List packages together, and fix or add menuTitles. (#70338)

List packages together, and fix or add menuTitles.

(cherry picked from commit a50afe67d3)

Co-authored-by: Ursula Kallio <ursula.kallio@grafana.com>
2023-06-19 11:34:49 -04:00
Dimitris Sotirakis
85637f0355 [v9.4.x] What's New: Bump whatsnewurl link (#70313)
Bump whatsNewUrl link
2023-06-19 13:11:11 +03:00
Jack Baldry
b3b5a9a999 [v9.4.x] Update make-docs procedure (#70275)
Update make-docs procedure (#70265)

## 4.1.0 (2023-06-16)

### Added

- Mounts of `layouts` and `config` directories for the `website` project.
  Ensures that local changes to mounts or shortcodes are reflected in the development server.

### Fixed

- Version inference for versioned docs pages.
  Pages in versioned projects now have the `versioned: true` front matter set to ensure that "version" in $.Page.Scratch is set on builds.

## 4.0.0 (2023-06-06)

### Removed

- `doc-validator/%` target.
  The behavior of the target was not as described.
  Instead, to limit `doc-validator` to only specific files, refer to https://grafana.com/docs/writers-toolkit/writing-guide/tooling-and-workflows/validate-technical-documentation/#run-on-specific-files.

## 3.0.0 (2023-05-18)

### Fixed

- Compatibility with the updated Make targets in the `website` repository.
  `docs` now runs this script itself, `server-docs` builds the site with the `docs` Hugo environment.


(cherry picked from commit a4a16b62c7)

Signed-off-by: Jack Baldry <jack.baldry@grafana.com>
2023-06-16 21:53:29 +01:00
Jack Baldry
4c56cef6af [v9.4.x] Use docs/reference for flexible linking for content reused in Grafana Cloud (#70270)
Use docs/reference for flexible linking for content reused in Grafana Cloud (#70253)

* Use docs/reference for flexible linking for content reused in Grafana Cloud

Documented in https://github.com/grafana/website/pull/13878



* Use docs-base image that has docs/reference shortcode



---------


(cherry picked from commit 3d15d54a71)

Signed-off-by: Jack Baldry <jack.baldry@grafana.com>
2023-06-16 18:45:27 +01:00
Grot (@grafanabot)
4c7ff6cff3 [v9.4.x] Changelog: Updated changelog for 9.4.10 (#70184)
Changelog: Updated changelog for 9.4.10 (#70181)

(cherry picked from commit 44c87c5b32)

Co-authored-by: Horst Gutmann <horst.gutmann@grafana.com>
2023-06-15 15:06:19 +00:00
Grot (@grafanabot)
1bb101b1ce [v9.4.x] Changelog: Updated changelog for 9.4.12 (#70171)
Changelog: Updated changelog for 9.4.12 (#70167)

(cherry picked from commit c82baf68a5)

Co-authored-by: Horst Gutmann <horst.gutmann@grafana.com>
2023-06-15 17:21:03 +03:00
Dimitris Sotirakis
ca2c251be6 [v9.4.x] CI: Update grabpl to v3.0.39 (#70134)
CI: Update `grabpl` to `v3.0.39` (#70126)

Update grabpl to v3.0.39

(cherry picked from commit b1e219e72c)

# Conflicts:
#	.drone.yml
2023-06-15 13:11:38 +03:00
Dimitris Sotirakis
c251570039 [v9.4.x] Bug: Fix build-frontend* config checks (#70076) (#70118)
Bug: Fix `build-frontend*` config checks (#70076)

* Fix frontend config checks

* Exclude test tag events

(cherry picked from commit 5a36fa5f8a)

# Conflicts:
#	pkg/build/cmd/buildfrontendpackages.go
2023-06-15 09:44:30 +03:00
Dimitris Sotirakis
c1cddece45 [v9.4.x] CI: Add CI check for what's new link (#70046) (#70121)
CI: Add CI check for `what's new` link (#70046)

* Add whatsnewchecker

* Add whatsnewchecker_test

* Small fixes

* Add step in CI

* Fix lint

* Fix starlark

* t.Cleanup instead of separate func

* Skip check for test tags

(cherry picked from commit 91272ee4f9)

# Conflicts:
#	.drone.yml
#	scripts/drone/events/release.star
2023-06-15 09:43:55 +03:00
Grot (@grafanabot)
37fc161fd9 [v9.4.x] AzureMonitor: Update docs to detail Azure logs query changes (#70086)
AzureMonitor: Update docs to detail Azure logs query changes (#69987)

Update docs to detail Azure logs query changes

(cherry picked from commit 068236c37f)

Co-authored-by: Andreas Christou <andreas.christou@grafana.com>
2023-06-14 19:14:11 +03:00
Dimitris Sotirakis
9117cec064 [v9.4.x] NPM packages: Fail build-frontend-packages step if package.json and input tag differ (#70011) (#70041)
* NPM packages: Fail `build-frontend-packages` step if `package.json` and input tag differ (#70011)

* Fail if package.json version is different than the tag

* Add tests

* Update message

* Small refactoring

* Fix lint

(cherry picked from commit a6b524fd56)

* Bump urfave/cli/v2

* go mod tidy
2023-06-14 12:42:05 +03:00
Dimitris Sotirakis
1a714ed0f5 [v9.4.x] Security Scans: Exclude windows container scans (#69977) (#69983)
Security Scans: Exclude windows container scans (#69977)

* Exclude windows container scans

* Fixes according to reviewer's comments

(cherry picked from commit fa70fba0e3)

# Conflicts:
#	.drone.yml
2023-06-13 10:57:32 +03:00
Isabel
f4064da4b5 [v9.4.x] docs: general edits to dashboard overview (#69747) (#69933)
docs: general edits to dashboard overview (#69747)

* general edits

* style edits - contractions

* Update docs/sources/fundamentals/dashboards-overview/index.md

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>

* Update docs/sources/fundamentals/dashboards-overview/index.md

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>

* Apply suggestions from code review

* fixed linting error

---------

Co-authored-by: David Allen <david.allen@grafana.com>
Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>
(cherry picked from commit a169cdd5ec)

# Conflicts:
#	docs/sources/fundamentals/dashboards-overview/index.md
2023-06-12 11:32:08 -04:00
Dimitris Sotirakis
0850edc137 [v9.4.x] Security Scans: Add trivy scans to every docker image used for building/testing/publishing (#69911) (#69920)
* Security Scans: Add trivy scans to every docker image used for building/testing/publishing (#69911)

* Created images.star

* Fix typo

* Add cronjobs for build-images

(cherry picked from commit 2cda971796)

# Conflicts:
#	.drone.yml
#	scripts/drone/services/services.star
#	scripts/drone/steps/lib.star

* Fix rebasing issue
2023-06-12 17:32:09 +03:00
Jack Westbrook
12c6626a42 [v9.4.x] Docs: fix broken migration-guide (#69896)
docs: fix broken migration-guide
2023-06-12 12:02:20 +02:00
Grot (@grafanabot)
e5d8b486a6 [v9.4.x] docs: Azure doc link update (#69751)
docs: Azure doc link update (#69749)

Update index.md

Link update

(cherry picked from commit 3e48c0b570)

Co-authored-by: Jan Garaj <jan.garaj@gmail.com>
2023-06-08 09:29:25 -05:00
Christopher Moyer
66f195ca77 [9.4.x] Backport 64565 to v9.4.x (#69746)
Docs/docker compose update (#64565)

* added CLI in heading for clearity

* added new heading

* new change

* updated final version for review

* fix small line breaks

* copy edit, restructuring

* Apply suggestions from code review

* Apply suggestions from code review

* removed internal notes

* updateding the docker configuraiton file which have advanced instructions

* Update docs/sources/setup-grafana/installation/docker/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/installation/docker/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/installation/docker/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/installation/docker/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/installation/docker/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/installation/docker/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/installation/docker/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/installation/docker/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* updated persistent stroage section

* updated heading typo

* Update docs/sources/setup-grafana/installation/docker/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/installation/docker/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/installation/docker/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/installation/docker/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/installation/docker/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/installation/docker/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/installation/docker/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/installation/docker/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/installation/docker/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/installation/docker/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* fixed code identation and minor typos

* added yaml file validation check in the troubleshooting section

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

added "also"

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* add more details to apline, cloudwatch and default path sections

* Apply suggestions from code review

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* added more detailes about docker ubuntu image, fixed headings, added more clarity to the persistent vs bind stroage

* Apply suggestions from code review

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* added more improvements for the examples

* Update docs/sources/setup-grafana/installation/docker/index.md

* Update docs/sources/setup-grafana/installation/docker/index.md

* Update docs/sources/setup-grafana/installation/docker/index.md

* Update docs/sources/setup-grafana/configure-docker.md

* updates links, edits Troubleshooting section

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Dan Cech <dcech@grafana.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Dan Cech <dcech@grafana.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Dan Cech <dcech@grafana.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Dan Cech <dcech@grafana.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Dan Cech <dcech@grafana.com>

* fixes doc-validator issues

* adds link to plugin install instructions

* added improvement in the AWS cloudwatch example

* Update docs/sources/setup-grafana/configure-docker.md

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Apply suggestions from code review

suggestions looks good

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* added dan suggestion for the tags, but skip the longer description part as not really useful for end user

* Update docs/sources/setup-grafana/installation/docker/index.md

Co-authored-by: Dan Cech <dcech@grafana.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Dan Cech <dcech@grafana.com>

* Update docs/sources/setup-grafana/configure-docker.md

Co-authored-by: Dan Cech <dcech@grafana.com>

* Apply suggestions from code review

looks good

Co-authored-by: Dan Cech <dcech@grafana.com>

* added missing version

* fixed identation and small typo

* fixed the pwd data folder instruction

* fixed persistent volume creating and identation

* fixed identation

* fixed typo to get debug logs

* fixed custom plugin installation section

* created docker secret command instructions

* fixed missing path

* fixed code in docker secret and other minor typos

* incorporates feedback, copy edits secrets section

* fixed small typo in docker secrets section

* remove the additonal info command for secrets

* combined custom docker pre-installed plugin section as one

* fixed the build link typo

* various updates/fixes

* another fix

* added more clarity to the volume creating command

* fixed command for bind mounts

* fixed missing comman in the plugin command

* fixed small typo

* improve and simplifly the steps instructions

* fixed validation command

* Apply suggestions from code review

looks good!!

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* fixed typo in docker secret command explaination

* fixed minor stuff

* makes prettier

---------

Co-authored-by: Chris Moyer <chris.moyer@grafana.com>
Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>
Co-authored-by: Dan Cech <dcech@grafana.com>
(cherry picked from commit d50e50be28)

Co-authored-by: Usman Ahmad <usman.ahmad@grafana.com>
2023-06-07 15:06:30 -05:00
Isabel
c659f65ac0 [v9.4.x] docs: improvements to visualizations docs (#69740)
fixing merge conflict
2023-06-07 14:18:20 -04:00
Grot (@grafanabot)
5cbce7b951 [v9.4.x] docs: add product labels for reporting page (#69726)
docs: add product labels for reporting page (#69717)

add product labels for reporting page

(cherry picked from commit 994defeeb4)

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
2023-06-07 12:04:52 -04:00
Grot (@grafanabot)
8c42bef420 [v9.4.x] Docker: Add ARM64 architecture for Docker, for PRs (#69713)
Docker: Add ARM64 architecture for Docker, for PRs (#68295)

* Add ARM64 architecture for Docker

* Add arm64 variants

(cherry picked from commit bbd83cbaeb)

Co-authored-by: Dimitris Sotirakis <dimitrios.sotirakis@grafana.com>
2023-06-07 17:35:23 +03:00
Grot (@grafanabot)
d3d03312c3 [v9.4.x] Docs: Remove duplicate word in edit panel of configure panel options (#69666)
Docs: Remove duplicate word in edit panel of configure panel options (#69592)

Documentation: Remove duplicate word in edit panel of configure panel options
(cherry picked from commit f20a8eb2a7)

Co-authored-by: SatVeer Singh <developer.satveer@gmail.com>
2023-06-06 16:53:37 -04:00
Grot (@grafanabot)
c97d52e238 [v9.4.x] docs: update use dashboards descriptions (#69492)
* docs: update use dashboards descriptions (#67360)

* Update index.md

* fix wording

---------

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
(cherry picked from commit eeb08a4662)

* reverting incorrectly backported changes

* add changes intended for backport

* revert incorrectly backported change

---------

Co-authored-by: MattiasSegerdahl <102952046+MattiasSegerdahl@users.noreply.github.com>
Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
2023-06-06 16:37:13 -04:00
Grot (@grafanabot)
8faf41ff7f [v9.4.x] Prevent crash while executing concurrent mixed queries (#876)
Prevent crash while executing concurrent mixed queries (#874)

limit parallel query execution to 1 at a time

(cherry picked from commit 96579a60e19e2a9f2d6bdaeba64e0e702211eb73)

Co-authored-by: Michael Mandrus <41969079+mmandrus@users.noreply.github.com>
2023-06-06 13:27:09 +02:00
George Robinson
f30c03c281 [v9.4.x] Require alert.notifications:write permissions to test receivers and templates (#868)
Require alert.notifications:write permissions to test receivers and templates (#865)

(cherry picked from commit 3c21ab70075256d4ba8e4fbfdcb15f5a394161fa)
2023-06-06 13:27:08 +02:00
Grot (@grafanabot)
1e75a11e6b Release: Bump version to 9.4.13 (#69618)
"Release: Updated versions in package to 9.4.13"
2023-06-06 10:11:42 +00:00
Horst Gutmann
ce81d3d30a [v9.4.x] Changelog: Updated changelog for 9.4.12 (#69619)
* Changelog: Updated changelog for 9.4.12

* Add missing changes

Backport of #69617

---------

Co-authored-by: Horst Gutmann <horst.gutmann@grafana.com>
(cherry picked from commit 997c5e2348)

Co-authored-by: Grot (@grafanabot) <43478413+grafanabot@users.noreply.github.com>
2023-06-06 11:49:02 +02:00
Grot (@grafanabot)
92f437a5f2 [v9.4.x] Chore: Update @grafana/e2e (#66881)
Chore: Update @grafana/e2e (#66365)

* Update e2e package

- Ensure health request is monitored for addDatasource flow
- Add custom timeout to configurePanel flow

* Make health check optional

(cherry picked from commit b2e32a70b9)

Co-authored-by: Andreas Christou <andreas.christou@grafana.com>
2023-06-05 09:33:22 +00:00
Grot (@grafanabot)
16b542a3e6 [v9.4.x] [docs] typo fixes in expression queries (#69505)
[docs] typo fixes in expression queries (#65665)

* Update index.md

Fixing some minor typos.

* make language clearer

---------

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
(cherry picked from commit 6e501b9c07)

Co-authored-by: marybelvargas <107340764+marybelvargas@users.noreply.github.com>
2023-06-02 18:19:23 -04:00
Grot (@grafanabot)
0167cb7ff8 [v9.4.x] docs: update add-template-variables docs (#69500)
docs: update add-template-variables docs (#65682)

correcting typo in "Filter and modify using named text and value capture groups" section

(cherry picked from commit 921bc0324e)

Co-authored-by: annelaurefroment <49911675+annelaurefroment@users.noreply.github.com>
2023-06-02 17:56:08 -04:00
Grot (@grafanabot)
f6273ebb06 [v9.4.x] docs: fix grafana play link (#69496)
docs: fix grafana play link (#65763)

* Update index.md

Fixed the link for a grafana play reference

* fix link text

* fix wording for flow

---------

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
(cherry picked from commit 5dc07dedaa)

Co-authored-by: ashley <97468854+ansomerv@users.noreply.github.com>
2023-06-02 17:51:56 -04:00
Grot (@grafanabot)
4c1f6cca24 [v9.4.x] docs: update TestData screenshots (#69481)
docs: update TestData screenshots (#69472)

updated screenshots

(cherry picked from commit 52da729c83)

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
2023-06-02 16:25:39 -04:00
Grot (@grafanabot)
de801f532d [v9.4.x] Docs: Bring back the alias for external group sync HTTP API page (#69455)
Docs: Bring back the alias for external group sync HTTP API page (#69434)

* Docs: Bring back the alias for external group sync HTTP API page

* Update docs/sources/developers/http_api/team_sync.md

Co-authored-by: Jack Baldry <jack.baldry@grafana.com>

---------

Co-authored-by: Jack Baldry <jack.baldry@grafana.com>
(cherry picked from commit 0e5e5175b1)

Co-authored-by: Vardan Torosyan <vardants@gmail.com>
2023-06-02 13:08:05 +00:00
Grot (@grafanabot)
457b4b208b [v9.4.x] remove incorrect state changes statement (#69446)
remove incorrect state changes statement (#65785)

Update index.md

(cherry picked from commit e789c2bf03)

Co-authored-by: Stefan Dunkler <stefan.dun@gmail.com>
2023-06-02 13:58:09 +02:00
Grot (@grafanabot)
0828eaa14c [v9.4.x] Docs: Rename External Group Sync references to Team Sync (#69398)
Docs: Rename External Group Sync references to Team Sync (#69395)

(cherry picked from commit 8235f774aa)

Co-authored-by: Vardan Torosyan <vardants@gmail.com>
2023-06-02 11:01:57 +02:00
Grot (@grafanabot)
832e89dad0 [v9.4.x] Dashboard: Fix library panels in collapsed rows not getting updated (#68535)
Dashboard: Fix library panels in collapsed rows not getting updated (#66643)

(cherry picked from commit f478504bc9)

Co-authored-by: Victor Colomb <51762123+VictorColomb@users.noreply.github.com>
2023-06-01 11:56:20 +03:00
Grot (@grafanabot)
caa6545292 [v9.4.x] Fix opentsdb table format (#69283)
Fix opentsdb table format (#69281)

* fixed table formatting

* changed opentsdb to OpenTSDB

* cleaned up wording

(cherry picked from commit 4a84633773)

Co-authored-by: lwandz13 <126723338+lwandz13@users.noreply.github.com>
2023-05-30 13:44:49 -07:00
Grot (@grafanabot)
0ac3eb956b [v9.4.x] Auth: Update docs on use PKCE by default (#69267)
Auth: Update docs on use PKCE by default (#68638)

* Auth: Update docs on use PKCE by default. (#68073)

Signed-off-by: junya koyama <arukiidou@yahoo.co.jp>

* Fix: docs review - from introduces to provides https://github.com/grafana/grafana/pull/68638/files#r1200506006

Signed-off-by: junya koyama <arukiidou@yahoo.co.jp>

* Fix docs - Remove note about a version https://github.com/grafana/grafana/pull/68638/files#r1200508038

Signed-off-by: junya koyama <arukiidou@yahoo.co.jp>

* Update docs/sources/setup-grafana/configure-security/configure-authentication/azuread/index.md

---------

Signed-off-by: junya koyama <arukiidou@yahoo.co.jp>
Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>
(cherry picked from commit 345b7fadc9)

Co-authored-by: arukiidou <arukiidou@yahoo.co.jp>
2023-05-30 11:41:53 -05:00
Grot (@grafanabot)
4cf03f5004 [v9.4.x] Docs: adds intro to prometheus (#69263)
Docs: adds intro to prometheus (#64352)

* adds topic content

* adjusts weights

* Update docs/sources/fundamentals/intro-to-prometheus/index.md

Co-authored-by: Fiona Artiaga <89225282+GrafanaWriter@users.noreply.github.com>

* Update docs/sources/fundamentals/intro-to-prometheus/index.md

* Apply suggestions from code review

Co-authored-by: Fiona Artiaga <89225282+GrafanaWriter@users.noreply.github.com>
Co-authored-by: Eve Meelan <81647476+Eve832@users.noreply.github.com>

* Update docs/sources/fundamentals/intro-to-prometheus/index.md

* Apply suggestions from code review

Co-authored-by: Eve Meelan <81647476+Eve832@users.noreply.github.com>

* Apply suggestions from code review

* adds sentence about agent

* reworks prometheus as deployment section based on feedback

---------

Co-authored-by: Fiona Artiaga <89225282+GrafanaWriter@users.noreply.github.com>
Co-authored-by: Eve Meelan <81647476+Eve832@users.noreply.github.com>
(cherry picked from commit 59a62353dd)

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>
2023-05-30 10:58:12 -05:00
Grot (@grafanabot)
e3f05514d3 [v9.4.x] Docs: Updates Grafana [smtp](#63311) (#69215)
Docs: Updates Grafana [smtp](#63311) (#63332)

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>
Co-authored-by: Emil Tullstedt <emil.tullstedt@grafana.com>
(cherry picked from commit 89088d6aa2)

Co-authored-by: chenbt <34958405+chenbt-hz@users.noreply.github.com>
2023-05-30 09:14:55 -05:00
Grot (@grafanabot)
6d94ee5411 [v9.4.x] fix: Chef cookbook has moved to sous-chefs (#69240)
fix: Chef cookbook has moved to sous-chefs (#68425)

* fix: Chef cookbook has moved to sous-chefs

Updates the github link for the chef configuration option.

* Update docs/sources/administration/provisioning/index.md

Co-authored-by: Jack Baldry <jack.baldry@grafana.com>

---------

Co-authored-by: Jack Baldry <jack.baldry@grafana.com>
(cherry picked from commit 1ff5170c83)

Co-authored-by: Jason Field <Jason@avon-lea.co.uk>
2023-05-30 08:32:05 +01:00
Ricky Whitaker
8be48da766 Backport 69191 to v9.4.x (#69197)
* fix verify_release_pipeline script execution (#69191)

* fix verify_release_pipeline script execution

* forgot to run make drone

(cherry picked from commit 68fe1e1cb0)

* make drone

---------

Co-authored-by: Kevin Minehart <kmineh0151@gmail.com>
2023-05-26 17:20:21 -05:00
Joseph Perez
ef87202878 [v9.4.x] Docs: Plugins doc review chunk 1-B (#68926)
Docs: Plugin doc review changes from chunk 1-B with corrected set of files (#67164)

* Re-pushing doc review changes from 1-B with fewer files

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

* Fix for URL examples

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

* Data frames fixes

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

* Fixes from doc review

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

* More doc review changes

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

* Doc fixes

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

* Doc fix

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

* Prettier

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

* Fix migration index

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

* Fix screenshot

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

* Doc fixes

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

* Quick fix

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

---------

Signed-off-by: Joe Perez <joseph.perez@grafana.com>
(cherry picked from commit d6ba522c3c)
2023-05-26 19:29:32 +02:00
Grot (@grafanabot)
d448263073 [v9.4.x] Docs: Plugin doc review - backend topics - chunk 5 (#69161)
Docs: Plugin doc review - backend topics - chunk 5 (#68662)

* Initial commit

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

* Minor fixes

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

* Prettier fixes

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

* Incorporating review feedback

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

* Minor fix

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

* Update docs/sources/developers/plugins/backend/_index.md

Co-authored-by: Giuseppe Guerra <giuseppe.guerra@grafana.com>

* Update docs/sources/developers/plugins/backend/_index.md

Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com>

* Update docs/sources/developers/plugins/backend/_index.md

Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com>

* Update docs/sources/developers/plugins/backend/_index.md

Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com>

* Update docs/sources/developers/plugins/backend/_index.md

Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com>

* Update docs/sources/developers/plugins/backend/_index.md

Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com>

* Update docs/sources/developers/plugins/backend/_index.md

Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com>

* Update docs/sources/developers/plugins/backend/_index.md

Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com>

* Update docs/sources/developers/plugins/backend/_index.md

Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com>

* Update docs/sources/developers/plugins/backend/_index.md

Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com>

* Update docs/sources/developers/plugins/backend/grafana-plugin-sdk-for-go.md

Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com>

* Update docs/sources/developers/plugins/backend/grafana-plugin-sdk-for-go.md

Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com>

* Update docs/sources/developers/plugins/backend/plugin-protocol.md

Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com>

* Update docs/sources/developers/plugins/backend/plugin-protocol.md

Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com>

* Update docs/sources/developers/plugins/backend/plugin-protocol.md

Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com>

* Update docs/sources/developers/plugins/backend/_index.md

Co-authored-by: David Harris <david.harris@grafana.com>

* Indentation fix

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

* Review feedback

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

* Bug fix

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

---------

Signed-off-by: Joe Perez <joseph.perez@grafana.com>
Co-authored-by: Giuseppe Guerra <giuseppe.guerra@grafana.com>
Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com>
Co-authored-by: David Harris <david.harris@grafana.com>
(cherry picked from commit b7e2f3ad3f)

Co-authored-by: Joseph Perez <45749060+josmperez@users.noreply.github.com>
2023-05-26 16:48:37 +00:00
Grot (@grafanabot)
fc447be8ac [v9.4.x] Docs: Update the service account HTTP API documentation (#69187)
Docs: Update the service account HTTP API documentation (#63235)

* doc: Add the service account deletion function

* doc: Add new service account documentation

(cherry picked from commit 4aa207ed83)

Co-authored-by: Pascal Zimmermann <pascal.zimmermann@theiotstudio.com>
2023-05-26 09:39:11 -07:00
Grot (@grafanabot)
f498b4d821 [v9.4.x] Docs: corrects circular reference in links (#69169)
Docs: corrects circular reference in links (#69165)

corrects circular reference in links

(cherry picked from commit 521d5f86dc)

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>
2023-05-26 08:57:12 -05:00
Grot (@grafanabot)
f781e6fb7e [v9.4.x] Docs: fix 2 broken links on 'Publish a plugin' topic (#69157)
Docs: fix 2 broken links on 'Publish a plugin' topic (#68666)

* Initial commit

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

* Delete Reference folder for now

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

---------

Signed-off-by: Joe Perez <joseph.perez@grafana.com>
(cherry picked from commit 0600c5f5e7)

Co-authored-by: Joseph Perez <45749060+josmperez@users.noreply.github.com>
2023-05-26 08:25:11 -05:00
Grot (@grafanabot)
e6ed9908e3 [v9.4.x] GoogleAPI: Add retries functionallity to GoogleAPI calls (#69142)
GoogleAPI: Add retries functionallity to GoogleAPI calls (#69129)

* Add retryer to GoogleAPI calls

* Add comment

(cherry picked from commit 515270f5fd)

Co-authored-by: Dimitris Sotirakis <dimitrios.sotirakis@grafana.com>
2023-05-26 10:21:16 +00:00
Grot (@grafanabot)
37a8711985 [v9.4.x] docs: Update "Create reports" doc to clarify custom time ranges and add information about drafts (#69090)
docs: Update "Create reports" doc to clarify custom time ranges and add information about drafts (#69015)

* Update index.md

Clarify that changes to dashboard time range are only reflected in the report if they are not using a custom time range.

Add information regarding saving a report as a draft.

* Update docs/sources/dashboards/create-reports/index.md

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>

* running prettier

---------

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
Co-authored-by: Isabel Matwawana <isabel.matwawana@grafana.com>
(cherry picked from commit 9a5262d5c8)

Co-authored-by: chrisharbro <102977229+chrisharbro@users.noreply.github.com>
2023-05-25 19:02:19 -04:00
Grot (@grafanabot)
cd0854f1bc [v9.4.x] docs: update logs integration and calculation types content (#68915)
* Jasuade docs patch 1 (#68074)

* Docs update Logs in Explore

* Include new Calculation Types :docs:

* Update docs/sources/explore/logs-integration.md

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>

* Update docs/sources/explore/logs-integration.md

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>

* Update docs/sources/explore/logs-integration.md

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>

* Update docs/sources/explore/logs-integration.md

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>

* Eye icon instead of Toggle field visibility

* running prettier

---------

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
Co-authored-by: Isabel Matwawana <isabel.matwawana@grafana.com>
(cherry picked from commit 753c9c262c)

* fixing erroneously updated content

* remove extra line break

---------

Co-authored-by: Jara Suárez de Puga García <jara.suarezdepuga@grafana.com>
Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
2023-05-26 01:33:43 +03:00
Grot (@grafanabot)
0d7c6950b9 [v9.4.x] Docs: Add JSON format for webhook notifications to differences (#69054)
Docs: Add JSON format for webhook notifications to differences (#68786)

(cherry picked from commit 65e2df7a2e)

Co-authored-by: George Robinson <george.robinson@grafana.com>
2023-05-25 11:17:48 +02:00
Horst Gutmann
58b306eacf [v9.4.x] CI: Pin the google/cloud-sdk image (#69041)
[v9.4.x] CI: Pin the google/cloud-sdk image (#69037)

(cherry picked from commit f22d1d14a0)

Backport of #69037
2023-05-25 10:56:33 +03:00
Grot (@grafanabot)
0d80fc0da0 [v9.4.x] update prometheus query editor doc (#69012)
update prometheus query editor doc (#68595)

* initial updates to outdated info

* minor edits prior to draft PR

* commented out options no longer available

* additional edits

* removed tables, changed format to list

* updated code mode section

* finished edits to builder mode

* added revisions per Brendan

* removed commented out section

* added note short codes

(cherry picked from commit 3edeafa663)

Co-authored-by: lwandz13 <126723338+lwandz13@users.noreply.github.com>
2023-05-24 13:38:11 -07:00
Grot (@grafanabot)
14d0a0cfd5 [v9.4.x] Edit global time variable - custom date formats use browser time (#69019)
Edit global time variable - custom date formats use browser time (#69016)

* Edit global time variable - custom date formats use browser time

Fixes https://github.com/grafana/grafana/issues/68748

* run prettier

---------

Co-authored-by: Eve Meelan <81647476+Eve832@users.noreply.github.com>
(cherry picked from commit 7c2358862e)

Co-authored-by: Melori Arellano <melori.arellano@grafana.com>
2023-05-24 13:37:09 -07:00
Grot (@grafanabot)
8ba86ce233 [v9.4.x] "Anatomy of a Dashboard" intro docs (#68833)
"Anatomy of a Dashboard" intro docs (#68011)

* first commit

* Update docs/sources/fundamentals/dashboards-overview/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/fundamentals/dashboards-overview/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/fundamentals/dashboards-overview/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/fundamentals/dashboards-overview/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/fundamentals/dashboards-overview/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/fundamentals/dashboards-overview/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* applying edited suggestions

* applying edit changes

* Update docs/sources/fundamentals/dashboards-overview/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/fundamentals/dashboards-overview/index.md

* Update docs/sources/fundamentals/dashboards-overview/index.md

* Update docs/sources/fundamentals/dashboards-overview/index.md

* Update docs/sources/fundamentals/dashboards-overview/index.md

* Update docs/sources/fundamentals/dashboards-overview/index.md

* Update docs/sources/fundamentals/dashboards-overview/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/fundamentals/dashboards-overview/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/fundamentals/dashboards-overview/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/fundamentals/dashboards-overview/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Update docs/sources/fundamentals/dashboards-overview/index.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

* makes prettier

---------

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>
Co-authored-by: Chris Moyer <chris.moyer@grafana.com>
(cherry picked from commit 26c59ddc70)

Co-authored-by: David Allen <david.allen@grafana.com>
2023-05-24 09:51:35 -05:00
Jack Baldry
7daa240753 Revert "[v9.4.x] [feat] docs; update admonition syntax" (#68982)
Revert "[v9.4.x] [feat] docs; update admonition syntax (#68855)"

This reverts commit 048de5d09a.
2023-05-24 14:53:21 +01:00
Kevin Minehart
136cb16a52 [9.4.x] Backport 68756 to v9.4.x (#68932)
CI: Add release verify pipeline (#68756)

(cherry picked from commit 79f49c9649)
2023-05-24 15:20:48 +02:00
Dimitris Sotirakis
324ba5c62b [v9.4.x] G10: Replace beta with preview references (#68347) (#68948)
G10: Replace `beta` with `preview` references (#68347)

* Update references

* Update grabpl to v3.0.38

(cherry picked from commit 7e816d010c)

# Conflicts:
#	.drone.yml
2023-05-24 02:21:50 -07:00
Dimitris Sotirakis
81d4d8f228 [v9.4.x] Remove code to publish to RPM and deb repos (#61786) (#68952)
Remove code to publish to RPM and deb repos (#61786)

This was replaced here: https://github.com/grafana/grafana/pull/53553 and it's no longer used

(cherry picked from commit a190e03133)

Co-authored-by: Julien Duchesne <julien.duchesne@grafana.com>
2023-05-24 10:49:30 +02:00
Grot (@grafanabot)
70d0b7a0d2 [v9.4.x] Docs: Plugins doc review chunk 3 (#68919)
Docs: Plugins doc review chunk 3 (#68159)

* Initial commit

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

* Minor fix

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

* Review changes

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

* Doc fixes

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

* Minor fix

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

* Update docs/sources/developers/plugins/cross-plugin-linking.md

Co-authored-by: Matt Dodson <47385188+MattDodsonEnglish@users.noreply.github.com>

* Update docs/sources/developers/plugins/development-with-local-grafana.md

Co-authored-by: Matt Dodson <47385188+MattDodsonEnglish@users.noreply.github.com>

* Update docs/sources/developers/plugins/cross-plugin-linking.md

Co-authored-by: Matt Dodson <47385188+MattDodsonEnglish@users.noreply.github.com>

* Update docs/sources/developers/plugins/cross-plugin-linking.md

Co-authored-by: Matt Dodson <47385188+MattDodsonEnglish@users.noreply.github.com>

* Update docs/sources/developers/plugins/development-with-local-grafana.md

Co-authored-by: Matt Dodson <47385188+MattDodsonEnglish@users.noreply.github.com>

* Incorporating review feedback

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

* Update docs/sources/developers/plugins/development-with-local-grafana.md

Co-authored-by: Matt Dodson <47385188+MattDodsonEnglish@users.noreply.github.com>

* Test commit

Signed-off-by: Joe Perez <joseph.perez@grafana.com>

---------

Signed-off-by: Joe Perez <joseph.perez@grafana.com>
Co-authored-by: Matt Dodson <47385188+MattDodsonEnglish@users.noreply.github.com>
(cherry picked from commit d68079e927)

Co-authored-by: Joseph Perez <45749060+josmperez@users.noreply.github.com>
2023-05-23 14:23:38 -05:00
Grot (@grafanabot)
4b802788f5 [v9.4.x] Update enterprise plugins list (#68911)
Update enterprise plugins list (#68730)

Updated to reflect a couple missing plugins from https://grafana.com/docs/plugins/

(cherry picked from commit 34d294bf56)

Co-authored-by: Ron D <106610617+rgnvldr@users.noreply.github.com>
2023-05-23 14:14:30 -05:00
Grot (@grafanabot)
048de5d09a [v9.4.x] [feat] docs; update admonition syntax (#68855)
[feat] docs; update admonition syntax (#68842)

* [feat] docs; update admonition syntax

- Standardizes according to style conventions: https://grafana.com/docs/writers-toolkit/style-guide/style-conventions/#admonitions
- Prepares docs for better, uniform admonition style.

* Remove false positives and irregularities

* false positive removal

* Update docs/sources/datasources/mysql/_index.md

* Update docs/sources/developers/angular_deprecation/angular-plugins.md

* fix link errors

* Prettify some nested blockquotes

* remoe unnecessary admonition

(cherry picked from commit 1c4bb9ca00)

Co-authored-by: Matt Dodson <47385188+MattDodsonEnglish@users.noreply.github.com>
2023-05-23 07:46:19 -05:00
Grot (@grafanabot)
ad2a920191 [v9.4.x] Azure Monitor: Fix bug that did not show alert rule preview (#68561)
Azure Monitor: Fix bug that did not show alert rule preview (#68339)

(cherry picked from commit f9601f8f27)

Co-authored-by: Alyssa Bull <58453566+alyssabull@users.noreply.github.com>
2023-05-23 13:33:39 +01:00
Grot (@grafanabot)
c794e68ea2 [v9.4.x] Docker: Add mode label when building docker images (#68868)
Docker: Add `mode` label when building docker images (#68865)

Add mode label when building docker image

(cherry picked from commit bad570ee86)

Co-authored-by: Dimitris Sotirakis <dimitrios.sotirakis@grafana.com>
2023-05-23 10:56:06 +02:00
Grot (@grafanabot)
4d944081bc [v9.4.x] Utils: Reimplement util.GetRandomString to avoid modulo bias (#66969)
Utils: Reimplement util.GetRandomString to avoid modulo bias (#64481)

* reimplement GetRandomString, add tests that results are unbiased

(cherry picked from commit 7e765c870a)

Co-authored-by: Dan Cech <dcech@grafana.com>
2023-05-22 14:55:20 -04:00
399 changed files with 12438 additions and 15278 deletions

7
.codespellignore Normal file
View File

@@ -0,0 +1,7 @@
aks
eror
iam
wan
[Operato Windrose](https://grafana.com/grafana/plugins/operato-windrose-panel/)
sergent
showIn

View File

@@ -7,62 +7,51 @@
This module returns a Drone configuration including pipelines and secrets.
"""
load("scripts/drone/events/pr.star", "pr_pipelines")
load("scripts/drone/events/cron.star", "cronjobs")
load("scripts/drone/events/main.star", "main_pipelines")
load("scripts/drone/events/pr.star", "pr_pipelines")
load(
"scripts/drone/events/release.star",
"artifacts_page_pipeline",
"enterprise2_pipelines",
"enterprise_pipelines",
"integration_test_pipelines",
"oss_pipelines",
"publish_artifacts_pipelines",
"publish_npm_pipelines",
"publish_packages_pipeline",
)
load(
"scripts/drone/pipelines/publish_images.star",
"publish_image_pipelines_public",
"publish_image_pipelines_security",
)
load(
"scripts/drone/pipelines/ci_images.star",
"publish_ci_build_container_image_pipeline",
"publish_ci_windows_test_image_pipeline",
)
load("scripts/drone/pipelines/github.star", "publish_github_pipeline")
load("scripts/drone/pipelines/aws_marketplace.star", "publish_aws_marketplace_pipeline")
load(
"scripts/drone/pipelines/publish_images.star",
"publish_image_pipelines_public",
)
load(
"scripts/drone/pipelines/windows.star",
"windows_test_backend",
)
load("scripts/drone/version.star", "version_branch_pipelines")
load("scripts/drone/events/cron.star", "cronjobs")
load(
"scripts/drone/rgm.star",
"rgm",
)
load("scripts/drone/vault.star", "secrets")
def main(_ctx):
return (
pr_pipelines() +
main_pipelines() +
oss_pipelines() +
enterprise_pipelines() +
enterprise2_pipelines() +
publish_image_pipelines_public() +
publish_image_pipelines_security() +
publish_github_pipeline("public") +
publish_github_pipeline("security") +
publish_aws_marketplace_pipeline("public") +
publish_artifacts_pipelines("security") +
publish_artifacts_pipelines("public") +
publish_npm_pipelines() +
publish_packages_pipeline() +
rgm() +
[windows_test_backend({
"event": ["promote"],
"target": ["test-windows"],
}, "oss", "testing")] +
artifacts_page_pipeline() +
version_branch_pipelines() +
integration_test_pipelines() +
publish_ci_windows_test_image_pipeline() +
publish_ci_build_container_image_pipeline() +
cronjobs() +
secrets()
)

6403
.drone.yml

File diff suppressed because it is too large Load Diff

5
.github/CODEOWNERS vendored
View File

@@ -234,6 +234,7 @@ WORKFLOW.md @torkelo
/Dockerfile @grafana/grafana-delivery
/Makefile @grafana/grafana-delivery
/scripts/build/ @grafana/grafana-delivery
/scripts/list-release-artifacts.sh @grafana/grafana-delivery
# OSS Plugin Partnerships backend code
/pkg/tsdb/cloudwatch/ @grafana/aws-plugins
@@ -576,6 +577,7 @@ embed.go @grafana/grafana-as-code
/.github/pr-commands.json @marefr
/.github/renovate.json5 @grafana/frontend-ops
/.github/teams.yml @armandgrillet
/.github/workflows/auto-milestone.yml @grafana/grafana-delivery
/.github/workflows/backport.yml @grafana/grafana-delivery
/.github/workflows/bump-version.yml @grafana/grafana-delivery
/.github/workflows/close-milestone.yml @grafana/grafana-delivery
@@ -598,6 +600,8 @@ embed.go @grafana/grafana-as-code
/.github/workflows/pr-codeql-analysis-python.yml @DanCech
/.github/workflows/pr-commands-closed.yml @tolzhabayev
/.github/workflows/pr-commands.yml @marefr
/.github/workflows/pr-patch-check.yml @grafana/grafana-delivery
/.github/workflows/sync-mirror.yml @grafana/grafana-delivery
/.github/workflows/publish-technical-documentation-next.yml @grafana/docs-grafana
/.github/workflows/publish-technical-documentation-release.yml @grafana/docs-grafana
/.github/workflows/remove-milestone.yml @grafana/user-essentials
@@ -607,6 +611,7 @@ embed.go @grafana/grafana-as-code
/.github/workflows/stale.yml @grafana/user-essentials
/.github/workflows/update-changelog.yml @grafana/grafana-delivery
/.github/workflows/snyk.yml @grafana/security-team
/.github/workflows/create-security-patch-from-security-mirror.yml @grafana/grafana-delivery
# Conf
/conf/defaults.ini @torkelo

View File

@@ -46,4 +46,4 @@
},
"targetUrl": "https://github.com/grafana/grafana/blob/main/contribute/merge-pull-request.md#include-in-changelog-and-release-notes"
}
]
]

24
.github/workflows/auto-milestone.yml vendored Normal file
View File

@@ -0,0 +1,24 @@
name: Auto-milestone
on:
pull_request:
types:
- opened
- reopened
- closed
jobs:
main:
runs-on: ubuntu-latest
steps:
- name: "Generate token"
id: generate_token
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92
with:
app_id: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }}
private_key: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }}
- name: Run auto-milestone
uses: grafana/grafana-github-actions-go/auto-milestone@main
with:
pr: ${{ github.event.pull_request.number }}
token: ${{ steps.generate_token.outputs.token }}

View File

@@ -17,10 +17,16 @@ jobs:
ref: main
- name: Install Actions
run: npm install --production --prefix ./actions
- name: "Generate token"
id: generate_token
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92
with:
app_id: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }}
private_key: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }}
- name: Run backport
uses: ./actions/backport
with:
metricsWriteAPIKey: ${{secrets.GRAFANA_MISC_STATS_API_KEY}}
token: ${{secrets.GH_BOT_ACCESS_TOKEN}}
token: ${{ steps.generate_token.outputs.token }}
labelsToAdd: "backport,no-changelog"
title: "[{{base}}] {{originalTitle}}"

View File

@@ -6,12 +6,12 @@ on:
description: 'Needs to match, exactly, the name of a milestone. The version to be released please respect: major.minor.patch or major.minor.patch-beta<number> format. example: 7.4.3 or 7.4.3-beta1'
required: true
env:
YARN_ENABLE_IMMUTABLE_INSTALLS: false
YARN_ENABLE_IMMUTABLE_INSTALLS: false
jobs:
main:
runs-on: ubuntu-latest
steps:
# This is a basic workflow to help you get started with Actions
# This is a basic workflow to help you get started with Actions
- uses: actions-ecosystem/action-regex-match@v2.0.2
if: ${{ github.event.inputs.version != '' }}
id: regex-match
@@ -68,8 +68,14 @@ jobs:
node-version: '16'
- name: Install Actions
run: npm install --production --prefix ./actions
- name: Run bump version (manually invoked)
- name: "Generate token"
id: generate_token
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92
with:
app_id: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }}
private_key: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }}
- name: Run bump version (manually invoked)
uses: ./actions/bump-version
with:
token: ${{ secrets.GH_BOT_ACCESS_TOKEN }}
token: ${{ steps.generate_token.outputs.token }}
metricsWriteAPIKey: ${{ secrets.GRAFANA_MISC_STATS_API_KEY }}

View File

@@ -11,9 +11,7 @@ on:
description: Needs to match, exactly, the name of a milestone
required: true
type: string
secrets:
token:
required: true
jobs:
main:
runs-on: ubuntu-latest
@@ -26,14 +24,20 @@ jobs:
ref: main
- name: Install Actions
run: npm install --production --prefix ./actions
- name: "Generate token"
id: generate_token
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92
with:
app_id: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }}
private_key: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }}
- name: Close milestone (manually invoked)
if: ${{ github.event.inputs.version != '' }}
uses: ./actions/close-milestone
with:
token: ${{ secrets.GH_BOT_ACCESS_TOKEN }}
token: ${{ steps.generate_token.outputs.token }}
- name: Close milestone (workflow invoked)
if: ${{ inputs.version_call != '' }}
uses: ./actions/close-milestone
with:
version_call: ${{ inputs.version_call }}
token: ${{ secrets.token }}
token: ${{ steps.generate_token.outputs.token }}

View File

@@ -44,7 +44,7 @@ jobs:
name: Set go version
uses: actions/setup-go@v3
with:
go-version: '1.19.2'
go-version: '1.20.10'
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL

View File

@@ -0,0 +1,28 @@
# Owned by grafana-delivery-squad
# Intended to be dropped into the base repo (Ex: grafana/grafana) for use in the security mirror.
name: Create security patch
run-name: create-security-patch
on:
pull_request:
types:
- opened
- reopened
- synchronize
branches:
- "main"
- "v*.*.*"
# This is run before the pull request has been merged, so we'll run against the src branch
jobs:
trigger_downstream_create_security_patch:
concurrency: create-patch-${{ github.ref_name }}
uses: grafana/security-patch-actions/.github/workflows/create-patch.yml@main
if: github.repository == 'grafana/grafana-security-mirror'
with:
repo: "${{ github.repository }}"
src_ref: "${{ github.head_ref }}" # this is the source branch name, Ex: "feature/newthing"
patch_ref: "${{ github.base_ref }}" # this is the target branch name, Ex: "main"
patch_repo: "grafana/grafana-security-patches"
patch_prefix: "${{ github.event.pull_request.number }}"
secrets: inherit

View File

@@ -16,10 +16,16 @@ jobs:
ref: main
- name: Install Actions
run: npm install --production --prefix ./actions
- name: "Generate token"
id: generate_token
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92
with:
app_id: ${{ secrets.GRAFANA_PR_AUTOMATION_APP_ID }}
private_key: ${{ secrets.GRAFANA_PR_AUTOMATION_APP_PEM }}
- name: Repository Dispatch
uses: ./actions/repository-dispatch
with:
token: ${{ secrets.GH_BOT_ACCESS_TOKEN }}
token: ${{ steps.generate_token.outputs.token }}
repository: grafana/grafana-enterprise
event_type: oss-pull-request
client_payload:

View File

@@ -3,7 +3,7 @@ on:
workflow_dispatch:
inputs:
version:
required: true
required: true
description: Needs to match, exactly, the name of a milestone (NO v prefix)
jobs:
main:
@@ -14,11 +14,17 @@ jobs:
with:
repository: "grafana/grafana-github-actions"
path: ./actions
ref: main
ref: main
- name: Install Actions
run: npm install --production --prefix ./actions
- name: "Generate token"
id: generate_token
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92
with:
app_id: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }}
private_key: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }}
- name: Run github release action
uses: ./actions/github-release
with:
token: ${{secrets.GH_BOT_ACCESS_TOKEN}}
token: ${{ steps.generate_token.outputs.token }}
metricsWriteAPIKey: ${{secrets.GRAFANA_MISC_STATS_API_KEY}}

View File

@@ -10,12 +10,10 @@ jobs:
uses: grafana/grafana/.github/workflows/remove-milestone.yml@main
with:
version_call: ${{ github.event.inputs.version_input }}
secrets:
token: ${{ secrets.GH_BOT_ACCESS_TOKEN }}
secrets: inherit
call-close-milestone:
uses: grafana/grafana/.github/workflows/close-milestone.yml@main
with:
version_call: ${{ github.event.inputs.version_input }}
secrets:
token: ${{ secrets.GH_BOT_ACCESS_TOKEN }}
needs: call-remove-milestone
secrets: inherit
needs: call-remove-milestone

View File

@@ -23,7 +23,7 @@ jobs:
- name: Set go version
uses: actions/setup-go@v3
with:
go-version: '1.19.2'
go-version: '1.20.10'
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL

View File

@@ -2,25 +2,50 @@ name: PR automation
on:
pull_request_target:
types:
- labeled
- opened
- synchronize
concurrency:
group: pr-commands-${{ github.event.number }}
jobs:
config:
runs-on: "ubuntu-latest"
outputs:
has-secrets: ${{ steps.check.outputs.has-secrets }}
steps:
- name: "Check for secrets"
id: check
shell: bash
run: |
if [ -n "${{ (secrets.GRAFANA_PR_AUTOMATION_APP_ID != '' &&
secrets.GRAFANA_PR_AUTOMATION_APP_PEM != '' &&
secrets.GRAFANA_MISC_STATS_API_KEY != ''
) || '' }}" ]; then
echo "has-secrets=1" >> "$GITHUB_OUTPUT"
fi
main:
needs: config
if: needs.config.outputs.has-secrets
runs-on: ubuntu-latest
steps:
- name: Checkout Actions
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
repository: "grafana/grafana-github-actions"
path: ./actions
ref: main
- name: Install Actions
run: npm install --production --prefix ./actions
- name: "Generate token"
id: generate_token
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92
with:
app_id: ${{ secrets.GRAFANA_PR_AUTOMATION_APP_ID }}
private_key: ${{ secrets.GRAFANA_PR_AUTOMATION_APP_PEM }}
- name: Run Commands
uses: ./actions/commands
with:
metricsWriteAPIKey: ${{secrets.GRAFANA_MISC_STATS_API_KEY}}
token: ${{secrets.GH_BOT_ACCESS_TOKEN}}
token: ${{ steps.generate_token.outputs.token }}
configPath: pr-commands

26
.github/workflows/pr-patch-check.yml vendored Normal file
View File

@@ -0,0 +1,26 @@
# Owned by grafana-delivery-squad
# Intended to be dropped into the base repo Ex: grafana/grafana
name: Check for patch conflicts
run-name: check-patch-conflicts-${{ github.base_ref }}-${{ github.head_ref }}
on:
pull_request:
types:
- opened
- reopened
- synchronize
branches:
- "main"
- "v*.*.*"
- "release-*"
# Since this is run on a pull request, we want to apply the patches intended for the
# target branch onto the source branch, to verify compatibility before merging.
jobs:
trigger_downstream_patch_check:
uses: grafana/security-patch-actions/.github/workflows/test-patches.yml@main
with:
src_repo: "${{ github.repository }}"
src_ref: "${{ github.head_ref }}" # this is the source branch name, Ex: "feature/newthing"
patch_repo: "${{ github.repository }}-security-patches"
patch_ref: "${{ github.base_ref }}" # this is the target branch name, Ex: "main"
secrets: inherit

View File

@@ -11,9 +11,7 @@ on:
description: Needs to match, exactly, the name of a milestone
required: true
type: string
secrets:
token:
required: true
jobs:
main:
runs-on: ubuntu-latest
@@ -26,14 +24,20 @@ jobs:
ref: main
- name: Install Actions
run: npm install --production --prefix ./actions
- name: "Generate token"
id: generate_token
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92
with:
app_id: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }}
private_key: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }}
- name: Remove milestone from open issues (manually invoked)
if: ${{ github.event.inputs.version != '' }}
uses: ./actions/remove-milestone
with:
token: ${{ secrets.GH_BOT_ACCESS_TOKEN }}
token: ${{ steps.generate_token.outputs.token }}
- name: Remove milestone from open issues (workflow invoked)
if: ${{ inputs.version_call != '' }}
uses: ./actions/remove-milestone
with:
version_call: ${{ inputs.version_call }}
token: ${{ secrets.token }}
token: ${{ steps.generate_token.outputs.token }}

25
.github/workflows/sync-mirror.yml vendored Normal file
View File

@@ -0,0 +1,25 @@
# Owned by grafana-delivery-squad
# Intended to be dropped into the base repo, Ex: grafana/grafana
name: Sync to mirror
run-name: sync-to-mirror-${{ github.ref_name }}
on:
workflow_dispatch:
push:
branches:
- "main"
- "v*.*.*"
- "release-*"
# This is run after the pull request has been merged, so we'll run against the target branch
jobs:
trigger_downstream_patch_mirror:
concurrency: patch-mirror-${{ github.ref_name }}
uses: grafana/security-patch-actions/.github/workflows/mirror-branch-and-apply-patches.yml@main
if: github.repository == 'grafana/grafana'
with:
ref: "${{ github.ref_name }}" # this is the target branch name, Ex: "main"
src_repo: "${{ github.repository }}"
dest_repo: "${{ github.repository }}-security-mirror"
patch_repo: "${{ github.repository }}-security-patches"
secrets: inherit

View File

@@ -9,6 +9,12 @@ jobs:
main:
runs-on: ubuntu-latest
steps:
- name: "Generate token"
id: generate_token
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92
with:
app_id: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }}
private_key: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }}
- name: Checkout Actions
uses: actions/checkout@v3
with:
@@ -17,8 +23,8 @@ jobs:
ref: main
- name: Install Actions
run: npm install --production --prefix ./actions
- name: Run update changelog (manually invoked)
- name: Run update changelog (manually invoked)
uses: ./actions/update-changelog
with:
token: ${{ secrets.GH_BOT_ACCESS_TOKEN }}
token: ${{ steps.generate_token.outputs.token }}
metricsWriteAPIKey: ${{ secrets.GRAFANA_MISC_STATS_API_KEY }}

3
.gitignore vendored
View File

@@ -186,3 +186,6 @@ public/locales/*/grafana_old.json
deployment_tools_config.json
.betterer.cache
# Temporary file for backporting PRs
.pr-body.txt

View File

@@ -1,7 +1,82 @@
<!-- 9.4.17 START -->
# 9.4.17 (2023-10-11)
### Features and enhancements
- **Chore:** Upgrade Go to 1.20.10. [#76370](https://github.com/grafana/grafana/issues/76370), [@zerok](https://github.com/zerok)
- **SSE:** DSNode to update result with names to make each value identifiable by labels (only Graphite and TestData). [#74615](https://github.com/grafana/grafana/issues/74615), [@yuri-tceretian](https://github.com/yuri-tceretian)
### Bug fixes
- **BrowseDashboards:** Only remember the most recent expanded folder. [#74812](https://github.com/grafana/grafana/issues/74812), [@joshhunt](https://github.com/joshhunt)
- **SQL Datasources:** Fix variable throwing error if query returns no data. [#74609](https://github.com/grafana/grafana/issues/74609), [@mdvictor](https://github.com/mdvictor)
- **RBAC:** Chore fix hasPermissionInOrg. (Enterprise)
<!-- 9.4.17 END -->
<!-- 9.4.15 START -->
# 9.4.15 (2023-09-18)
### Features and enhancements
- **Chore:** Upgrade Alpine base image to 3.18.3. [#74996](https://github.com/grafana/grafana/issues/74996), [@zerok](https://github.com/zerok)
- **Chore:** Upgrade Go to 1.20.8. [#74981](https://github.com/grafana/grafana/issues/74981), [@zerok](https://github.com/zerok)
<!-- 9.4.15 END -->
<!-- 9.4.14 START -->
# 9.4.14 (2023-09-05)
### Features and enhancements
- **Prometheus:** Add present_over_time syntax highlighting. [#72366](https://github.com/grafana/grafana/issues/72366), [@arnaudlemaignen](https://github.com/arnaudlemaignen)
### Bug fixes
- **LDAP:** Fix user disabling. [#74318](https://github.com/grafana/grafana/issues/74318), [@gamab](https://github.com/gamab)
- **Plugins:** Only configure plugin proxy transport once. [#71740](https://github.com/grafana/grafana/issues/71740), [@wbrowne](https://github.com/wbrowne)
- **InfluxDB:** Interpolate retention policies. [#71202](https://github.com/grafana/grafana/issues/71202), [@itsmylife](https://github.com/itsmylife)
- **Azure Monitor:** Fix bug that did not show alert rule preview. [#68561](https://github.com/grafana/grafana/issues/68561), [@alyssabull](https://github.com/alyssabull)
<!-- 9.4.14 END -->
<!-- 9.4.13 START -->
# 9.4.13 (2023-06-22)
### Bug fixes
- **Auth:** Fixed CVE-2023-3128. [#70579](https://github.com/grafana/grafana/issues/70579), [@zerok](https://github.com/zerok)
<!-- 9.4.13 END -->
<!-- 9.4.12 START -->
# 9.4.12 (2023-06-06)
### Bug fixes
- **Query:** Prevent crash while executing concurrent mixed queries
- **Alerting:** Require alert.notifications:write permissions to test receivers and templates
- **RBAC:** Remove legacy AC editor and admin role on new dashboard route. [#68775](https://github.com/grafana/grafana/issues/68775), [@grafanabot](https://github.com/grafanabot)
- **Revert:** Allow editors to access GET /datasources. [#68653](https://github.com/grafana/grafana/issues/68653), [@grafanabot](https://github.com/grafanabot)
- **Explore:** Remove data source onboarding page. [#68642](https://github.com/grafana/grafana/issues/68642), [@grafanabot](https://github.com/grafanabot)
<!-- 9.4.12 END -->
<!-- 9.4.10 START -->
# 9.4.10 (2023-05-08)
### Features and enhancements
- **Chore:** Upgrade Go to 1.20.4. [#67760](https://github.com/grafana/grafana/issues/67760), [@papagian](https://github.com/papagian)
### Bug fixes
- **AzureMonitor:** Fix logs query multi-resource and timespan values. [#67931](https://github.com/grafana/grafana/issues/67931), [@grafanabot](https://github.com/grafanabot)
- **TimeSeries:** Fix leading null-fill for missing intervals. [#67572](https://github.com/grafana/grafana/issues/67572), [@leeoniya](https://github.com/leeoniya)
- **Alerting:** Fix misleading status code in provisioning API. [#67357](https://github.com/grafana/grafana/issues/67357), [@grafanabot](https://github.com/grafanabot)
- **Azure Monitor:** Fix bug that was not showing resources for certain locations. [#66617](https://github.com/grafana/grafana/issues/66617), [@grafanabot](https://github.com/grafanabot)
<!-- 9.4.10 END -->
<!-- 9.4.9 START -->
@@ -9,7 +84,18 @@
### Features and enhancements
- **Chore:** Upgrade Go to 1.20.3. [#66264](https://github.com/grafana/grafana/pull/66264), [@sakjur](https://github.com/sakjur)
- **Chore:** Upgrade Go to 1.20.3. [#66836](https://github.com/grafana/grafana/issues/66836), [@sakjur](https://github.com/sakjur)
### Bug fixes
- **Expressions/threshold:** Fix incorrect thresholds args length. [#66925](https://github.com/grafana/grafana/issues/66925), [@gillesdemey](https://github.com/gillesdemey)
- **Alerting:** Fix share URL for Prometheus rules on subpath (#66752). [#66802](https://github.com/grafana/grafana/issues/66802), [@gillesdemey](https://github.com/gillesdemey)
- **Trace View:** Update the queryType to traceql for checking if same trace when clicking span link. [#66670](https://github.com/grafana/grafana/issues/66670), [@ericmustin](https://github.com/ericmustin)
- **Google Cloud Monitoring:** Fix project variable. [#66602](https://github.com/grafana/grafana/issues/66602), [@asimpson](https://github.com/asimpson)
- **InfluxDB:** Fix querying with hardcoded retention policy. [#66587](https://github.com/grafana/grafana/issues/66587), [@itsmylife](https://github.com/itsmylife)
- **Auth:** Remove the session cookie only if it's invalid or revoked. [#66430](https://github.com/grafana/grafana/issues/66430), [@mgyongyosi](https://github.com/mgyongyosi)
- **AccessControl:** Allow editors to access GET /api/datasources. [#66375](https://github.com/grafana/grafana/issues/66375), [@mgyongyosi](https://github.com/mgyongyosi)
- **CloudMonitoring:** Add project selector for MQL editor[fix]. [#65844](https://github.com/grafana/grafana/issues/65844), [@alyssabull](https://github.com/alyssabull)
<!-- 9.4.9 END -->
<!-- 9.4.7 START -->

View File

@@ -1,8 +1,8 @@
# syntax=docker/dockerfile:1
ARG BASE_IMAGE=alpine:3.17
ARG JS_IMAGE=node:18-alpine3.17
ARG GO_IMAGE=golang:1.20.4-alpine3.17
ARG BASE_IMAGE=alpine:3.18.3
ARG JS_IMAGE=node:18-alpine3.18
ARG GO_IMAGE=golang:1.20.10-alpine3.18
ARG GO_SRC=go-builder
ARG JS_SRC=js-builder
@@ -55,6 +55,7 @@ COPY pkg pkg
COPY scripts scripts
COPY conf conf
COPY .github .github
COPY LICENSE ./
RUN make build-go
@@ -98,7 +99,7 @@ RUN if grep -i -q alpine /etc/issue; then \
elif grep -i -q ubuntu /etc/issue; then \
DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
apt-get install -y ca-certificates curl tzdata && \
apt-get install -y ca-certificates curl tzdata musl && \
apt-get autoremove -y && \
rm -rf /var/lib/apt/lists/*; \
else \
@@ -153,6 +154,7 @@ RUN if [ ! $(getent group "$GF_GID") ]; then \
COPY --from=go-src /tmp/grafana/bin/grafana* /tmp/grafana/bin/*/grafana* ./bin/
COPY --from=js-src /tmp/grafana/public ./public
COPY --from=go-src /tmp/grafana/LICENSE ./
EXPOSE 3000

128
Makefile
View File

@@ -13,9 +13,12 @@ GO = go
GO_FILES ?= ./pkg/...
SH_FILES ?= $(shell find ./scripts -name *.sh)
GO_BUILD_FLAGS += $(if $(GO_BUILD_DEV),-dev)
GO_BUILD_FLAGS += $(if $(GO_BUILD_DEV),-dev)
GO_BUILD_FLAGS += $(if $(GO_BUILD_TAGS),-build-tags=$(GO_BUILD_TAGS))
targets := $(shell echo '$(sources)' | tr "," " ")
GO_INTEGRATION_TESTS := $(shell find ./pkg -type f -name '*_test.go' -exec grep -l '^func TestIntegration' '{}' '+' | grep -o '\(.*\)/' | sort -u)
all: deps build
##@ Dependencies
@@ -33,35 +36,68 @@ node_modules: package.json yarn.lock ## Install node modules.
##@ Swagger
SPEC_TARGET = public/api-spec.json
MERGED_SPEC_TARGET := public/api-merged.json
ENTERPRISE_SPEC_TARGET = public/api-enterprise-spec.json
MERGED_SPEC_TARGET = public/api-merged.json
NGALERT_SPEC_TARGET = pkg/services/ngalert/api/tooling/api.json
$(NGALERT_SPEC_TARGET):
+$(MAKE) -C pkg/services/ngalert/api/tooling api.json
$(MERGED_SPEC_TARGET): $(SPEC_TARGET) $(NGALERT_SPEC_TARGET) $(SWAGGER) ## Merge generated and ngalert API specs
$(MERGED_SPEC_TARGET): swagger-oss-gen swagger-enterprise-gen $(NGALERT_SPEC_TARGET) $(SWAGGER) ## Merge generated and ngalert API specs
# known conflicts DsPermissionType, AddApiKeyCommand, Json, Duration (identical models referenced by both specs)
$(SWAGGER) mixin $(SPEC_TARGET) $(NGALERT_SPEC_TARGET) --ignore-conflicts -o $(MERGED_SPEC_TARGET)
$(SWAGGER) mixin $(SPEC_TARGET) $(ENTERPRISE_SPEC_TARGET) $(NGALERT_SPEC_TARGET) --ignore-conflicts -o $(MERGED_SPEC_TARGET)
$(SPEC_TARGET): $(SWAGGER) ## Generate API Swagger specification
swagger-oss-gen: $(SWAGGER) ## Generate API Swagger specification
@echo "re-generating swagger for OSS"
rm -f $(SPEC_TARGET)
SWAGGER_GENERATE_EXTENSION=false $(SWAGGER) generate spec -m -w pkg/server -o $(SPEC_TARGET) \
-x "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" \
-x "github.com/prometheus/alertmanager" \
-i pkg/api/swagger_tags.json \
--exclude-tag=alpha
--exclude-tag=alpha \
--exclude-tag=enterprise
swagger-api-spec: gen-go $(SPEC_TARGET) $(MERGED_SPEC_TARGET) validate-api-spec
# this file only exists if enterprise is enabled
ENTERPRISE_EXT_FILE = pkg/extensions/ext.go
ifeq ("$(wildcard $(ENTERPRISE_EXT_FILE))","") ## if enterprise is not enabled
swagger-enterprise-gen:
@echo "skipping re-generating swagger for enterprise: not enabled"
else
swagger-enterprise-gen: $(SWAGGER) ## Generate API Swagger specification
@echo "re-generating swagger for enterprise"
rm -f $(ENTERPRISE_SPEC_TARGET)
SWAGGER_GENERATE_EXTENSION=false $(SWAGGER) generate spec -m -w pkg/server -o $(ENTERPRISE_SPEC_TARGET) \
-x "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" \
-x "github.com/prometheus/alertmanager" \
-i pkg/api/swagger_tags.json \
--exclude-tag=alpha \
--include-tag=enterprise
endif
validate-api-spec: $(MERGED_SPEC_TARGET) $(SWAGGER) ## Validate API spec
swagger-gen: gen-go $(MERGED_SPEC_TARGET) swagger-validate
swagger-validate: $(MERGED_SPEC_TARGET) $(SWAGGER) ## Validate API spec
$(SWAGGER) validate $(<)
clean-api-spec:
rm $(SPEC_TARGET) $(MERGED_SPEC_TARGET) $(OAPI_SPEC_TARGET)
swagger-clean:
rm -f $(SPEC_TARGET) $(MERGED_SPEC_TARGET) $(OAPI_SPEC_TARGET)
.PHONY: cleanup-old-git-hooks
cleanup-old-git-hooks:
./scripts/cleanup-husky.sh
.PHONY: lefthook-install
lefthook-install: cleanup-old-git-hooks $(LEFTHOOK) # install lefthook for pre-commit hooks
$(LEFTHOOK) install -f
.PHONY: lefthook-uninstall
lefthook-uninstall: $(LEFTHOOK)
$(LEFTHOOK) uninstall
##@ OpenAPI 3
OAPI_SPEC_TARGET = public/openapi3.json
openapi3-gen: swagger-api-spec ## Generates OpenApi 3 specs from the Swagger 2 already generated
openapi3-gen: swagger-gen ## Generates OpenApi 3 specs from the Swagger 2 already generated
$(GO) run scripts/openapi3/openapi3conv.go $(MERGED_SPEC_TARGET) $(OAPI_SPEC_TARGET)
##@ Building
@@ -72,7 +108,7 @@ gen-cue: ## Do all CUE/Thema code generation
go generate ./public/app/plugins/gen.go
go generate ./pkg/kindsys/report.go
gen-go: $(WIRE) gen-cue
gen-go: $(WIRE)
@echo "generate go files"
$(WIRE) gen -tags $(WIRE_TAGS) ./pkg/server ./pkg/cmd/grafana-cli/runner
@@ -84,7 +120,7 @@ fix-cue: $(CUE)
gen-jsonnet:
go generate ./devenv/jsonnet
build-go: $(MERGED_SPEC_TARGET) gen-go ## Build all Go binaries.
build-go: gen-go ## Build all Go binaries.
@echo "build go files"
$(GO) run build.go $(GO_BUILD_FLAGS) build
@@ -126,19 +162,39 @@ test-go-unit: ## Run unit tests for backend with flags.
.PHONY: test-go-integration
test-go-integration: ## Run integration tests for backend with flags.
@echo "test backend integration tests"
$(GO) test -run Integration -covermode=atomic -timeout=30m ./pkg/...
$(GO) test -count=1 -run "^TestIntegration" -covermode=atomic -timeout=5m $(GO_INTEGRATION_TESTS)
.PHONY: test-go-integration-alertmanager
test-go-integration-alertmanager: ## Run integration tests for the remote alertmanager (config taken from the mimir_backend block).
@echo "test remote alertmanager integration tests"
$(GO) clean -testcache
AM_URL=http://localhost:8080 AM_TENANT_ID=test AM_PASSWORD=test \
$(GO) test -count=1 -run "^TestIntegrationRemoteAlertmanager" -covermode=atomic -timeout=5m ./pkg/services/ngalert/notifier/...
.PHONY: test-go-integration-postgres
test-go-integration-postgres: devenv-postgres ## Run integration tests for postgres backend with flags.
@echo "test backend integration postgres tests"
$(GO) clean -testcache
$(GO) list './pkg/...' | xargs -I {} sh -c 'GRAFANA_TEST_DB=postgres go test -run Integration -covermode=atomic -timeout=2m {}'
GRAFANA_TEST_DB=postgres \
$(GO) test -p=1 -count=1 -run "^TestIntegration" -covermode=atomic -timeout=10m $(GO_INTEGRATION_TESTS)
.PHONY: test-go-integration-mysql
test-go-integration-mysql: devenv-mysql ## Run integration tests for mysql backend with flags.
@echo "test backend integration mysql tests"
GRAFANA_TEST_DB=mysql \
$(GO) test -p=1 -count=1 -run "^TestIntegration" -covermode=atomic -timeout=10m $(GO_INTEGRATION_TESTS)
.PHONY: test-go-integration-redis
test-go-integration-redis: ## Run integration tests for redis cache.
@echo "test backend integration redis tests"
$(GO) clean -testcache
$(GO) list './pkg/...' | xargs -I {} sh -c 'GRAFANA_TEST_DB=mysql go test -run Integration -covermode=atomic -timeout=2m {}'
REDIS_URL=localhost:6379 $(GO) test -run IntegrationRedis -covermode=atomic -timeout=2m $(GO_INTEGRATION_TESTS)
.PHONY: test-go-integration-memcached
test-go-integration-memcached: ## Run integration tests for memcached cache.
@echo "test backend integration memcached tests"
$(GO) clean -testcache
MEMCACHED_HOSTS=localhost:11211 $(GO) test -run IntegrationMemcached -covermode=atomic -timeout=2m $(GO_INTEGRATION_TESTS)
test-js: ## Run tests for frontend.
@echo "test frontend"
@@ -162,19 +218,36 @@ shellcheck: $(SH_FILES) ## Run checks for shell scripts.
##@ Docker
TAG_SUFFIX=$(if $(WIRE_TAGS)!=oss,-$(WIRE_TAGS))
PLATFORM=linux/amd64
build-docker-full: ## Build Docker image for development.
@echo "build docker container"
DOCKER_BUILDKIT=1 \
docker build \
--tag grafana/grafana:dev .
tar -ch . | \
docker buildx build - \
--platform $(PLATFORM) \
--build-arg BINGO=false \
--build-arg GO_BUILD_TAGS=$(GO_BUILD_TAGS) \
--build-arg WIRE_TAGS=$(WIRE_TAGS) \
--build-arg COMMIT_SHA=$$(git rev-parse HEAD) \
--build-arg BUILD_BRANCH=$$(git rev-parse --abbrev-ref HEAD) \
--tag grafana/grafana$(TAG_SUFFIX):dev \
$(DOCKER_BUILD_ARGS)
build-docker-full-ubuntu: ## Build Docker image based on Ubuntu for development.
@echo "build docker container"
DOCKER_BUILDKIT=1 \
docker build \
--build-arg BASE_IMAGE=ubuntu:20.04 \
--build-arg GO_IMAGE=golang:1.20.4 \
--tag grafana/grafana:dev-ubuntu .
tar -ch . | \
docker buildx build - \
--platform $(PLATFORM) \
--build-arg BINGO=false \
--build-arg GO_BUILD_TAGS=$(GO_BUILD_TAGS) \
--build-arg WIRE_TAGS=$(WIRE_TAGS) \
--build-arg COMMIT_SHA=$$(git rev-parse HEAD) \
--build-arg BUILD_BRANCH=$$(git rev-parse --abbrev-ref HEAD) \
--build-arg BASE_IMAGE=ubuntu:22.04 \
--build-arg GO_IMAGE=golang:1.20.10 \
--tag grafana/grafana$(TAG_SUFFIX):dev-ubuntu \
$(DOCKER_BUILD_ARGS)
##@ Services
@@ -185,8 +258,6 @@ devenv:
@printf 'You have to define sources for this command \nexample: make devenv sources=postgres,openldap\n'
else
devenv: devenv-down ## Start optional services, e.g. postgres, prometheus, and elasticsearch.
$(eval targets := $(shell echo '$(sources)' | tr "," " "))
@cd devenv; \
./create_docker_compose.sh $(targets) || \
(rm -rf {docker-compose.yaml,conf.tmp,.env}; exit 1)
@@ -219,6 +290,9 @@ devenv-mysql:
protobuf: ## Compile protobuf definitions
bash scripts/protobuf-check.sh
bash pkg/plugins/backendplugin/pluginextensionv2/generate.sh
bash pkg/plugins/backendplugin/secretsmanagerplugin/generate.sh
bash pkg/services/store/entity/generate.sh
bash pkg/infra/grn/generate.sh
clean: ## Clean up intermediate build artifacts.
@echo "cleaning"
@@ -244,7 +318,7 @@ scripts/drone/TAGS: $(shell find scripts/drone -name '*.star')
etags --lang none --regex="/def \(\w+\)[^:]+:/\1/" --regex="/\s*\(\w+\) =/\1/" $^ -o $@
format-drone:
buildifier -r scripts/drone
buildifier --lint=fix -r scripts/drone
help: ## Display this help.
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)

View File

@@ -504,6 +504,9 @@ sigv4_verbose_logging = false
# Set to true to enable Azure authentication option for HTTP-based datasources
azure_auth_enabled = false
# Use email lookup in addition to the unique ID provided by the IdP
oauth_allow_insecure_email_lookup = false
#################################### Anonymous Auth ######################
[auth.anonymous]
# enable anonymous access
@@ -535,6 +538,11 @@ allowed_organizations =
role_attribute_path =
role_attribute_strict = false
allow_assign_grafana_admin = false
skip_org_role_sync = false
tls_skip_verify_insecure = false
tls_client_cert =
tls_client_key =
tls_client_ca =
#################################### GitLab Auth #########################
[auth.gitlab]
@@ -949,8 +957,8 @@ execute_alerts = true
# The timeout string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
evaluation_timeout = 30s
# Number of times we'll attempt to evaluate an alert rule before giving up on that evaluation. This option has a legacy version in the `[alerting]` section that takes precedence.
max_attempts = 3
# Number of times we'll attempt to evaluate an alert rule before giving up on that evaluation. The default value is 1.
max_attempts = 1
# Minimum interval to enforce between rule evaluations. Rules will be adjusted if they are less than this value or if they are not multiple of the scheduler interval (10s). Higher values can help with resource management as we'll schedule fewer evaluations over time. This option has a legacy version in the `[alerting]` section that takes precedence.
# The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.

View File

@@ -508,6 +508,9 @@
# Set to skip the organization role from JWT login and use system's role assignment instead.
; skip_org_role_sync = false
# Use email lookup in addition to the unique ID provided by the IdP
;oauth_allow_insecure_email_lookup = false
#################################### Anonymous Auth ######################
[auth.anonymous]
# enable anonymous access
@@ -539,6 +542,7 @@
;role_attribute_path =
;role_attribute_strict = false
;allow_assign_grafana_admin = false
;skip_org_role_sync = false
#################################### GitLab Auth #########################
[auth.gitlab]
@@ -939,8 +943,8 @@
# The timeout string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
;evaluation_timeout = 30s
# Number of times we'll attempt to evaluate an alert rule before giving up on that evaluation. This option has a legacy version in the `[alerting]` section that takes precedence.
;max_attempts = 3
# Number of times we'll attempt to evaluate an alert rule before giving up on that evaluation. The default value is 1.
;max_attempts = 1
# Minimum interval to enforce between rule evaluations. Rules will be adjusted if they are less than this value or if they are not multiple of the scheduler interval (10s). Higher values can help with resource management as we'll schedule fewer evaluations over time. This option has a legacy version in the `[alerting]` section that takes precedence.
# The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.

View File

@@ -13,7 +13,6 @@ The following checklist/summary should give you a quick overview of what to ask/
- Reviewed and approved?
- All checks passed?
- Proper pull request title?
- Milestone assigned?
- Add to changelog/release notes?
- Needs backporting?
@@ -40,10 +39,18 @@ See [formatting guidelines](create-pull-request.md#formatting-guidelines) for mo
### Assign a milestone
A milestone **should** be added to every pull request. Several things in the Grafana release process requires at least pull requests to be in a milestone, for example [generating changelog/release notes](#include-in-changelog-and-release-notes).
Several things in the Grafana release process requires at least pull requests to be in a milestone, for example [generating changelog/release notes](#include-in-changelog-and-release-notes).
This makes it easier to track what changes go into a certain release. Without this information, release managers have to go through git commits which is not an efficient process.
That being said, _you don't have to assign a milestone manually_ to a pull request.
Instead, when it is merged & closed then a bot will look for the most appropriate miletone and assign it to the pull request.
That milestone should always reflect the branch that the pull request is merged into.
For every major and minor release there is a milestone ending with `.x` (e.g. `10.0.x` for the 10.0.x releases).
Pull requests targetting `main` should use the `.x` milestone of the next minor (or major) version (you can find that version number inside the `package.json` file).
Backport pull requestss should use the version of the target branch (e.g. `9.4.x` for the `v9.4.x` branch).
### Include in changelog and release notes?
At Grafana we generate the [changelog](https://github.com/grafana/grafana/blob/main/CHANGELOG.md) and [release notes](https://grafana.com/docs/grafana/latest/release-notes/) based on merged pull requests. Including changes in the changelog/release notes is very important to provide a somewhat complete picture of what changes a Grafana release actually includes.
@@ -78,15 +85,15 @@ The changelog/release notes are divided into sections and here's a description o
**Features and enhancements:**
Milestone assigned and labeled with `add to changelog` and any of the other section rules don't apply.
Labeled with `add to changelog` and any of the other section rules don't apply.
**Bug fixes:**
Milestone assigned and labeled with `add to changelog` and either labeled with `type/bug` or the pull request title contains `fix` or `fixes`.
Labeled with `add to changelog` and either labeled with `type/bug` or the pull request title contains `fix` or `fixes`.
**Plugin development fixes & changes:**
Milestone assigned and labeled with `area/grafana/toolkit`, `area/grafana/ui` or `area/grafana/runtime`.
Labeled with `area/grafana/toolkit`, `area/grafana/ui` or `area/grafana/runtime`.
**Deprecations:**

View File

@@ -1,33 +1,8 @@
.PHONY: pull docs docs-quick docs-no-pull docs-test docs-local-static
.ONESHELL:
.DELETE_ON_ERROR:
export SHELL := bash
export SHELLOPTS := pipefail:errexit
MAKEFLAGS += --warn-undefined-variables
MAKEFLAGS += --no-builtin-rule
PODMAN = $(shell if command -v podman >/dev/null 2>&1; then echo podman; else echo docker; fi)
IMAGE = grafana/docs-base:latest
CONTENT_PATH = /hugo/content/docs/grafana/latest
LOCAL_STATIC_PATH = ../../website/static
PORT = 3002:3002
pull:
$(PODMAN) pull $(IMAGE)
docs: pull
$(PODMAN) run --init -v $(shell pwd)/sources:$(CONTENT_PATH):Z -p $(PORT) --rm -it $(IMAGE) make server
docs-preview: pull
$(PODMAN) run --init -v $(shell pwd)/sources:$(CONTENT_PATH):Z -p $(PORT) --rm -it $(IMAGE) make server BUILD_DRAFTS=true
docs-no-pull:
$(PODMAN) run --init -v $(shell pwd)/sources:$(CONTENT_PATH):Z -p $(PORT) --rm -it $(IMAGE) make server
docs-test: pull
$(PODMAN) run --init -v $(shell pwd)/sources:$(CONTENT_PATH):Z --rm -it $(IMAGE) make prod
# expects that you have grafana/website checked out in same path as the grafana repo.
docs-local-static: pull
if [ ! -d "$(LOCAL_STATIC_PATH)" ]; then echo "local path (website project) $(LOCAL_STATIC_PATH) not found"]; exit 1; fi
$(PODMAN) run --init -v $(shell pwd)/sources:$(CONTENT_PATH):Z \
-v $(shell pwd)/$(LOCAL_STATIC_PATH):/hugo/static:Z -p $(PORT) --rm -it $(IMAGE)
.PHONY: doc-validator/%
doc-validator/%: ## Run doc-validator on a specific path. To lint the path /docs/sources/administration, run 'make doc-validator/administration'.
doc-validator/%:
$(PODMAN) run --init -v "$(shell pwd)/sources:/sources" grafana/doc-validator:latest --skip-image-validation --include=$(subst doc-validator/,,$@) ./sources /docs/grafana/latest
include docs.mk

View File

@@ -1,16 +1,21 @@
# Building the docs locally
When you contribute to documentation, it is a good practice to build the docs on your local machine to make sure your changes appear as you expect. This README explains the process for doing that.
When you contribute to documentation, it's a good practice to build the docs on your local machine to make sure your changes appear as you expect. This README explains the process for doing that.
To build a local version, you need to run a process in a Docker container.
Grafana periodically updates the Docker image, [`docs-base`](https://hub.docker.com/r/grafana/docs-base), to update the styling of the Docs.
## Requirements
Docker >= 2.1.0.3
Yarn >= 1.22.4
- Docker >= 2.1.0.3
- Yarn >= 1.22.4
## Build the doc site
First, make sure the Docker daemon is running on your machine. Then, follow these steps:
1. On the command line, first change to the docs folder: `cd docs`.
1. Run `make docs`. This launches a preview of the website with the current grafana docs at `http://localhost:3002/docs/grafana/next/` which will refresh automatically when changes are made to content in the `sources` directory.
1. Run `make docs`. This launches a preview of the website with the current grafana docs at `http://localhost:3002/docs/grafana/latest/` which will refresh automatically when changes are made to content in the `sources` directory.
If you have the grafana/website repo checked out in the same directory as the grafana repo, then you can run `make docs-local-static` to use local assets (such as images).
@@ -52,7 +57,7 @@ To specify different menu text from the page title, use the front matter paramet
### Add images
Images are currently hosted in the grafana/website repo.
Please see our help documentation on [Image, diagram, and screenshot guidelines](https://grafana.com/docs/writers-toolkit/writing-guide/image-guidelines/) for comprehensive information.
---

117
docs/docs.mk Normal file
View File

@@ -0,0 +1,117 @@
# The source of this file is https://raw.githubusercontent.com/grafana/writers-toolkit/main/docs/docs.mk.
# A changelog is included in the head of the `make-docs` script.
include variables.mk
-include variables.mk.local
.ONESHELL:
.DELETE_ON_ERROR:
export SHELL := bash
export SHELLOPTS := pipefail:errexit
MAKEFLAGS += --warn-undefined-variables
MAKEFLAGS += --no-builtin-rule
.DEFAULT_GOAL: help
# Adapted from https://www.thapaliya.com/en/writings/well-documented-makefiles/
.PHONY: help
help: ## Display this help.
help:
@awk 'BEGIN { \
FS = ": ##"; \
printf "Usage:\n make <target>\n\nTargets:\n" \
} \
/^[a-zA-Z0-9_\.\-\/%]+: ##/ { printf " %-15s %s\n", $$1, $$2 }' \
$(MAKEFILE_LIST)
GIT_ROOT := $(shell git rev-parse --show-toplevel)
PODMAN := $(shell if command -v podman >/dev/null 2>&1; then echo podman; else echo docker; fi)
ifeq ($(PROJECTS),)
$(error "PROJECTS variable must be defined in variables.mk")
endif
# First project is considered the primary one used for doc-validator.
PRIMARY_PROJECT := $(subst /,-,$(firstword $(subst :, ,$(firstword $(PROJECTS)))))
# Name for the container.
ifeq ($(origin DOCS_CONTAINER), undefined)
export DOCS_CONTAINER := $(PRIMARY_PROJECT)-docs
endif
# Host port to publish container port to.
ifeq ($(origin DOCS_HOST_PORT), undefined)
export DOCS_HOST_PORT := 3002
endif
# Container image used to perform Hugo build.
ifeq ($(origin DOCS_IMAGE), undefined)
export DOCS_IMAGE := grafana/docs-base:latest
endif
# Container image used for doc-validator linting.
ifeq ($(origin DOC_VALIDATOR_IMAGE), undefined)
export DOC_VALIDATOR_IMAGE := grafana/doc-validator:latest
endif
# Container image used for vale linting.
ifeq ($(origin VALE_IMAGE), undefined)
export VALE_IMAGE := grafana/vale:latest
endif
# PATH-like list of directories within which to find projects.
# If all projects are checked out into the same directory, ~/repos/ for example, then the default should work.
ifeq ($(origin REPOS_PATH), undefined)
export REPOS_PATH := $(realpath $(GIT_ROOT)/..)
endif
# How to treat Hugo relref errors.
ifeq ($(origin HUGO_REFLINKSERRORLEVEL), undefined)
export HUGO_REFLINKSERRORLEVEL := WARNING
endif
.PHONY: docs-rm
docs-rm: ## Remove the docs container.
$(PODMAN) rm -f $(DOCS_CONTAINER)
.PHONY: docs-pull
docs-pull: ## Pull documentation base image.
$(PODMAN) pull -q $(DOCS_IMAGE)
make-docs: ## Fetch the latest make-docs script.
make-docs:
if [[ ! -f "$(CURDIR)/make-docs" ]]; then
echo 'WARN: No make-docs script found in the working directory. Run `make update` to download it.' >&2
exit 1
fi
.PHONY: docs
docs: ## Serve documentation locally, which includes pulling the latest `DOCS_IMAGE` (default: `grafana/docs-base:latest`) container image. See also `docs-no-pull`.
docs: docs-pull make-docs
$(CURDIR)/make-docs $(PROJECTS)
.PHONY: docs-no-pull
docs-no-pull: ## Serve documentation locally without pulling the `DOCS_IMAGE` (default: `grafana/docs-base:latest`) container image.
docs-no-pull: make-docs
$(CURDIR)/make-docs $(PROJECTS)
.PHONY: docs-debug
docs-debug: ## Run Hugo web server with debugging enabled. TODO: support all SERVER_FLAGS defined in website Makefile.
docs-debug: make-docs
WEBSITE_EXEC='hugo server --bind 0.0.0.0 --port 3002 --debug' $(CURDIR)/make-docs $(PROJECTS)
.PHONY: doc-validator
doc-validator: ## Run doc-validator on the entire docs folder.
doc-validator: make-docs
DOCS_IMAGE=$(DOC_VALIDATOR_IMAGE) $(CURDIR)/make-docs $(PROJECTS)
.PHONY: vale
vale: ## Run vale on the entire docs folder.
vale: make-docs
DOCS_IMAGE=$(VALE_IMAGE) $(CURDIR)/make-docs $(PROJECTS)
.PHONY: update
update: ## Fetch the latest version of this Makefile and the `make-docs` script from Writers' Toolkit.
curl -s -LO https://raw.githubusercontent.com/grafana/writers-toolkit/main/docs/docs.mk
curl -s -LO https://raw.githubusercontent.com/grafana/writers-toolkit/main/docs/make-docs
chmod +x make-docs

656
docs/make-docs Executable file
View File

@@ -0,0 +1,656 @@
#!/bin/sh
# The source of this file is https://raw.githubusercontent.com/grafana/writers-toolkit/main/docs/make-docs.
# # `make-docs` procedure changelog
#
# Updates should conform to the guidelines in https://keepachangelog.com/en/1.1.0/.
# [Semantic versioning](https://semver.org/) is used to help the reader identify the significance of changes.
# Changes are relevant to this script and the support docs.mk GNU Make interface.
# ## 4.2.1 (2023-09-13)
# ## Fixed
# - Improved consistency of the webserver request loop by polling the Hugo port rather than the proxy port.
# ## 4.2.0 (2023-09-01)
# ### Added
# - Retry the initial webserver request up to ten times to allow for the process to start.
# If it is still failing after ten seconds, an error message is logged.
# ## 4.1.1 (2023-07-20)
# ### Fixed
# - Replaced use of `realpath` with POSIX compatible alternative to determine default value for REPOS_PATH.
# ## 4.1.0 (2023-06-16)
# ### Added
# - Mounts of `layouts` and `config` directories for the `website` project.
# Ensures that local changes to mounts or shortcodes are reflected in the development server.
# ### Fixed
# - Version inference for versioned docs pages.
# Pages in versioned projects now have the `versioned: true` front matter set to ensure that "version" in $.Page.Scratch is set on builds.
# ## 4.0.0 (2023-06-06)
# ### Removed
# - `doc-validator/%` target.
# The behavior of the target was not as described.
# Instead, to limit `doc-validator` to only specific files, refer to https://grafana.com/docs/writers-toolkit/writing-guide/tooling-and-workflows/validate-technical-documentation/#run-on-specific-files.
# ## 3.0.0 (2023-05-18)
# ### Fixed
# - Compatibility with the updated Make targets in the `website` repository.
# `docs` now runs this script itself, `server-docs` builds the site with the `docs` Hugo environment.
# ## 2.0.0 (2023-05-18)
# ### Added
# - Support for the grafana-cloud/frontend-observability/faro-web-sdk project.
# - Use of `doc-validator` v2.0.x which includes breaking changes to command line options.
# ### Fixed
# - Source grafana-cloud project from website repository.
# ### Added
# - Support for running the Vale linter with `make vale`.
# ## 1.2.1 (2023-05-05)
# ### Fixed
# - Use `latest` tag of `grafana/vale` image by default instead of hardcoded older version.
# - Fix mounting multiple projects broken by the changes in 1.0.1
# ## 1.2.0 (2023-05-05)
# ### Added
# - Support for running the Vale linter with `make vale`.
# ### Fixed
# ## 1.1.0 (2023-05-05)
# ### Added
# - Rewrite error output so it can be followed by text editors.
# ### Fixed
# - Fix `docs-debug` container process port.
# ## 1.0.1 (2023-05-04)
# ### Fixed
# - Ensure complete section hierarchy so that all projects have a visible menu.
# ## 1.0.0 (2023-05-04)
# ### Added
# - Build multiple projects simultaneously if all projects are checked out locally.
# - Run [`doc-validator`](https://github.com/grafana/technical-documentation/tree/main/tools/cmd/doc-validator) over projects.
# - Redirect project root to mounted version.
# For example redirect `/docs/grafana/` to `/docs/grafana/latest/`.
# - Support for Podman or Docker containers with `PODMAN` environment variable.
# - Support for projects:
# - agent
# - enterprise-logs
# - enterprise-metrics
# - enterprise-traces
# - grafana
# - grafana-cloud
# - grafana-cloud/machine-learning
# - helm-charts/mimir-distributed
# - helm-charts/tempo-distributed
# - incident
# - loki
# - mimir
# - oncall
# - opentelemetry
# - phlare
# - plugins
# - slo
# - tempo
# - writers-toolkit
set -ef
readonly DOCS_CONTAINER="${DOCS_CONTAINER:-make-docs}"
readonly DOCS_HOST_PORT="${DOCS_HOST_PORT:-3002}"
readonly DOCS_IMAGE="${DOCS_IMAGE:-grafana/docs-base:latest}"
readonly DOC_VALIDATOR_INCLUDE="${DOC_VALIDATOR_INCLUDE:-.+\.md$}"
readonly DOC_VALIDATOR_SKIP_CHECKS="${DOC_VALIDATOR_SKIP_CHECKS:-^image-}"
readonly HUGO_REFLINKSERRORLEVEL="${HUGO_REFLINKSERRORLEVEL:-WARNING}"
readonly VALE_MINALERTLEVEL="${VALE_MINALERTLEVEL:-error}"
readonly WEBSITE_EXEC="${WEBSITE_EXEC:-make server-docs}"
# If set, the docs-base image will run a prebuild script that sets up Hugo mounts.
readonly WEBSITE_MOUNTS="${WEBSITE_MOUNTS:-}"
PODMAN="$(if command -v podman >/dev/null 2>&1; then echo podman; else echo docker; fi)"
if ! command -v curl >/dev/null 2>&1; then
if ! command -v wget >/dev/null 2>&1; then
errr 'either `curl` or `wget` must be installed for this script to work.'
exit 1
fi
fi
if ! command -v "${PODMAN}" >/dev/null 2>&1; then
errr 'either `podman` or `docker` must be installed for this script to work.'
exit 1
fi
about() {
cat <<EOF
Test documentation locally with multiple source repositories.
The REPOS_PATH environment variable is a colon (:) separated list of paths in which to look for project repositories.
EOF
}
usage() {
cat <<EOF
Usage:
REPOS_PATH=<PATH[:<PATH>...]> $0 [<PROJECT>[:<VERSION>[:<REPO>[:<DIR>]]]...]
Examples:
REPOS_PATH=~/ext/grafana/ $0 writers-toolkit tempo:latest helm-charts/mimir-distributed:latest:mimir:docs/sources/mimir-distributed
EOF
}
if [ $# -lt 1 ]; then
cat <<EOF >&2
ERRR: arguments required but not supplied.
$(about)
$(usage)
EOF
exit 1
fi
readonly REPOS_PATH="${REPOS_PATH:-$(cd "$(git rev-parse --show-toplevel)/.." && echo "${PWD}")}"
if [ -z "${REPOS_PATH}" ]; then
cat <<EOF >&2
ERRR: REPOS_PATH environment variable is required but has not been provided.
$(usage)
EOF
exit 1
fi
SOURCES_as_code='as-code-docs'
SOURCES_enterprise_metrics='backend-enterprise'
SOURCES_enterprise_metrics_='backend-enterprise'
SOURCES_grafana_cloud='website'
SOURCES_grafana_cloud_alerting_and_irm_machine_learning='machine-learning'
SOURCES_grafana_cloud_alerting_and_irm_slo='slo'
SOURCES_grafana_cloud_k6='k6-docs'
SOURCES_grafana_cloud_data_configuration_integrations='cloud-onboarding'
SOURCES_grafana_cloud_frontend_observability_faro_web_sdk='faro-web-sdk'
SOURCES_helm_charts_mimir_distributed='mimir'
SOURCES_helm_charts_tempo_distributed='tempo'
SOURCES_opentelemetry='opentelemetry-docs'
SOURCES_plugins_grafana_splunk_datasource='splunk-datasource'
VERSIONS_as_code='UNVERSIONED'
VERSIONS_grafana_cloud='UNVERSIONED'
VERSIONS_grafana_cloud_alerting_and_irm_machine_learning='UNVERSIONED'
VERSIONS_grafana_cloud_alerting_and_irm_slo='UNVERSIONED'
VERSIONS_grafana_cloud_k6='UNVERSIONED'
VERSIONS_grafana_cloud_data_configuration_integrations='UNVERSIONED'
VERSIONS_grafana_cloud_frontend_observability_faro_web_sdk='UNVERSIONED'
VERSIONS_opentelemetry='UNVERSIONED'
VERSIONS_technical_documentation='UNVERSIONED'
VERSIONS_website='UNVERSIONED'
VERSIONS_writers_toolkit='UNVERSIONED'
PATHS_grafana_cloud='content/docs/grafana-cloud'
PATHS_helm_charts_mimir_distributed='docs/sources/helm-charts/mimir-distributed'
PATHS_helm_charts_tempo_distributed='docs/sources/helm-charts/tempo-distributed'
PATHS_mimir='docs/sources/mimir'
PATHS_tempo='docs/sources/tempo'
PATHS_website='content/docs'
# identifier STR
# Replace characters that are not valid in an identifier with underscores.
identifier() {
echo "$1" | tr -C '[:alnum:]_\n' '_'
}
# aget ARRAY KEY
# Get the value of KEY from associative array ARRAY.
# Characters that are not valid in an identifier are replaced with underscores.
aget() {
eval echo '$'"$(identifier "$1")_$(identifier "$2")"
}
# new_proj populates a new project structure.
new_proj() {
_project="$1"
_version="$2"
_repo="$3"
_path="$4"
# If version is not set, use the script mapping of project to default versions if it exists.
# Fallback to 'latest'.
if [ -z "${_version}" ]; then
if [ -z "$(aget VERSIONS "${_project}")" ]; then
_version=latest
else
_version="$(aget VERSIONS "${_project}")"
fi
fi
# If repo is not set, use the script mapping of project to repo name if it exists.
# Fallback to using the project name.
if [ -z "${_repo}" ]; then
if [ -z "$(aget SOURCES "${_project}")" ]; then
_repo="${_project}"
else
_repo="$(aget SOURCES "${_project}")"
fi
fi
# If path is not set, use the script mapping of project to docs sources path if it exists.
# Fallback to using 'docs/sources'.
if [ -z "${_path}" ]; then
if [ -z "$(aget PATHS "${_project}")" ]; then
_path="docs/sources"
else
_path="$(aget PATHS "${_project}")"
fi
fi
echo "${_project}:${_version}:${_repo}:${_path}"
unset _project _version _repo _path
}
# proj_url returns the webserver URL for a project.
# It expects a complete project structure as input.
proj_url() {
IFS=: read -r _project _version _ _ <<POSIX_HERESTRING
$1
POSIX_HERESTRING
if [ "${_project}" = 'website' ]; then
echo "http://localhost:${DOCS_HOST_PORT}/docs/"
unset _project _version
return
fi
if [ -z "${_version}" ] || [ "${_version}" = 'UNVERSIONED' ]; then
echo "http://localhost:${DOCS_HOST_PORT}/docs/${_project}/"
else
echo "http://localhost:${DOCS_HOST_PORT}/docs/${_project}/${_version}/"
fi
unset _project _version
}
# proj_ver returns the version for a project.
# It expects a complete project structure as input.
proj_ver() {
IFS=: read -r _ _ver _ _ <<POSIX_HERESTRING
$1
POSIX_HERESTRING
echo "${_ver}"
unset _ver
}
# proj_dst returns the container path to content source for a project.
# It expects a complete project structure as input.
proj_dst() {
IFS=: read -r _project _version _ _ <<POSIX_HERESTRING
$1
POSIX_HERESTRING
if [ "${_project}" = 'website' ]; then
echo '/hugo/content/docs'
unset _project _version
return
fi
if [ -z "${_version}" ] || [ "${_version}" = 'UNVERSIONED' ]; then
echo "/hugo/content/docs/${_project}"
else
echo "/hugo/content/docs/${_project}/${_version}"
fi
unset _project _version
}
# repo_path returns the host path to the project repository.
# It looks for the provided repository name in each of the paths specified in the REPOS_PATH environment variable.
repo_path() {
_repo="$1"
IFS=:
for lookup in ${REPOS_PATH}; do
if [ -d "${lookup}/${_repo}" ]; then
echo "${lookup}/${_repo}"
unset _path _repo
return
fi
done
unset IFS
errr "could not find project '${_repo}' in any of the paths in REPOS_PATH '${REPOS_PATH}'."
note "you must have a checkout of the project '${_repo}' at '${REPOS_PATH##:*}/${_repo}'."
note "if you have cloned the repository into a directory with a different name, consider changing it to ${_repo}."
unset _repo
exit 1
}
# proj_src returns the host path to content source for a project.
# It expects a complete project structure as input.
# It looks for the provided repository name in each of the paths specified in the REPOS_PATH environment variable.
proj_src() {
IFS=: read -r _ _ _repo _path <<POSIX_HERESTRING
$1
POSIX_HERESTRING
_repo="$(repo_path "${_repo}")"
echo "${_repo}/${_path}"
unset _path _repo
}
# proj_canonical returns the canonical absolute path partial URI for a project.
# It expects a complete project structure as input.
proj_canonical() {
IFS=: read -r _project _version _ _ <<POSIX_HERESTRING
$1
POSIX_HERESTRING
if [ "${_project}" = 'website' ]; then
echo '/docs'
unset _project _version
return
fi
if [ -z "${_version}" ] || [ "${_version}" = 'UNVERSIONED' ]; then
echo "/docs/${_project}"
else
echo "/docs/${_project}/${_version}"
fi
unset _project _version
}
proj_to_url_src_dst_ver() {
_url="$(proj_url "$1")"
_src="$(proj_src "$1")"
_dst="$(proj_dst "$1")"
_ver="$(proj_ver "$1")"
echo "${_url}^${_src}^${_dst}^${_ver}"
unset _url _src _dst _ver
}
url_src_dst_vers() {
for arg in "$@"; do
IFS=: read -r _project _version _repo _path <<POSIX_HERESTRING
$arg
POSIX_HERESTRING
case "${_project}" in
# Workaround for arbitrary mounts where the version field is expected to be the local directory
# and the repo field is expected to be the container directory.
arbitrary)
echo "${_project}^${_version}^${_repo}^" # TODO
;;
logs)
proj_to_url_src_dst_ver "$(new_proj loki "${_version}")"
proj_to_url_src_dst_ver "$(new_proj enterprise-logs "${_version}")"
;;
metrics)
proj_to_url_src_dst_ver "$(new_proj mimir "${_version}")"
proj_to_url_src_dst_ver "$(new_proj helm-charts/mimir-distributed "${_version}")"
proj_to_url_src_dst_ver "$(new_proj enterprise-metrics "${_version}")"
;;
traces)
proj_to_url_src_dst_ver "$(new_proj tempo "${_version}")"
proj_to_url_src_dst_ver "$(new_proj enterprise-traces "${_version}")"
;;
*)
proj_to_url_src_dst_ver "$(new_proj "${_project}" "${_version}" "${_repo}" "${_path}")"
;;
esac
done
unset _project _version _repo _path
}
await_build() {
url="$1"
req="$(if command -v curl >/dev/null 2>&1; then echo 'curl -s -o /dev/null'; else echo 'wget -q'; fi)"
i=1
max=10
while [ "${i}" -ne "${max}" ]
do
sleep 1
debg "Retrying request to webserver assuming the process is still starting up."
i=$((i + 1))
if ${req} "${url}"; then
echo
echo "View documentation locally:"
for x in ${url_src_dst_vers}; do
IFS='^' read -r url _ _ <<POSIX_HERESTRING
$x
POSIX_HERESTRING
if [ -n "${url}" ]; then
if [ "${_url}" != "arbitrary" ]; then
echo " ${url}"
fi
fi
done
echo
echo 'Press Ctrl+c to stop the server'
unset i max req url
return
fi
done
echo
errr 'The build was interrupted or a build error occurred, check the previous logs for possible causes.'
note 'You might need to use Ctrl+c to end the process.'
unset i max req url
}
debg() {
if [ -n "${DEBUG}" ]; then
echo "DEBG: $1" >&2
fi
}
errr() {
echo "ERRR: $1" >&2
}
note() {
echo "NOTE: $1" >&2
}
url_src_dst_vers="$(url_src_dst_vers "$@")"
volumes=""
redirects=""
for arg in "$@"; do
IFS=: read -r _project _ _repo _ <<POSIX_HERESTRING
${arg}
POSIX_HERESTRING
if [ "${_project}" = website ]; then
_repo="$(repo_path website)"
volumes="--volume=${_repo}/config:/hugo/config"
volumes="${volumes} --volume=${_repo}/layouts/partials:/hugo/layouts/partials"
volumes="${volumes} --volume=${_repo}/layouts/shortcodes:/hugo/layouts/shortcodes"
fi
unset _project _repo
done
for x in ${url_src_dst_vers}; do
IFS='^' read -r _url _src _dst _ver <<POSIX_HERESTRING
$x
POSIX_HERESTRING
if [ "${_url}" != "arbitrary" ]; then
if [ ! -f "${_src}/_index.md" ]; then
errr "Index file '${_src}/_index.md' does not exist."
note "Is '${_src}' the correct source directory?"
exit 1
fi
fi
debg "DEBG: Mounting '${_src}' at container path '${_dst}'"
if [ -z "${volumes}" ]; then
volumes="--volume=${_src}:${_dst}"
else
volumes="${volumes} --volume=${_src}:${_dst}"
fi
if [ -n "${_ver}" ] && [ "${_ver}" != 'UNVERSIONED' ]; then
if [ -z "${redirects}" ]; then
redirects="${_dst}^${_ver}"
else
redirects="${redirects} ${_dst}^${_ver}"
fi
fi
unset _url _src _dst _ver
done
IFS=':' read -r image _ <<POSIX_HERESTRING
${DOCS_IMAGE}
POSIX_HERESTRING
case "${image}" in
'grafana/doc-validator')
proj="$(new_proj "$1")"
echo
"${PODMAN}" run \
--init \
--interactive \
--name "${DOCS_CONTAINER}" \
--platform linux/amd64 \
--rm \
--tty \
${volumes} \
"${DOCS_IMAGE}" \
"--include=${DOC_VALIDATOR_INCLUDE}" \
"--skip-checks=${DOC_VALIDATOR_SKIP_CHECKS}" \
/hugo/content/docs \
"$(proj_canonical "${proj}")" | sed "s#$(proj_dst "${proj}")#sources#"
;;
'grafana/vale')
proj="$(new_proj "$1")"
echo
"${PODMAN}" run \
--init \
--interactive \
--name "${DOCS_CONTAINER}" \
--platform linux/amd64 \
--rm \
--tty \
${volumes} \
"${DOCS_IMAGE}" \
"--minAlertLevel=${VALE_MINALERTLEVEL}" \
--config=/etc/vale/.vale.ini \
--output=line \
/hugo/content/docs | sed "s#$(proj_dst "${proj}")#sources#"
;;
*)
tempfile="$(mktemp -t make-docs.XXX)"
cat <<EOF >"${tempfile}"
#!/usr/bin/env bash
for redirect in ${redirects}; do
IFS='^' read -r path ver <<<"\${redirect}"
echo -e "---\\nredirectURL: \"\${path/\/hugo\/content/}\"\\ntype: redirect\\nversioned: true\\n---\\n" > "\${path/\${ver}/_index.md}"
done
for x in "${url_src_dst_vers}"; do
IFS='^' read -r _ _ dst _ <<<"\${x}"
while [[ -n "\${dst}" ]]; do
touch "\${dst}/_index.md"
dst="\${dst%/*}"
done
done
if [[ -n "${WEBSITE_MOUNTS}" ]]; then
unset WEBSITE_SKIP_MOUNTS
fi
${WEBSITE_EXEC}
EOF
chmod +x "${tempfile}"
volumes="${volumes} --volume=${tempfile}:/entrypoint"
readonly volumes
IFS='' read -r cmd <<EOF
${PODMAN} run \
--env=HUGO_REFLINKSERRORLEVEL=${HUGO_REFLINKSERRORLEVEL} \
--init \
--interactive \
--name=${DOCS_CONTAINER} \
--platform=linux/amd64 \
--publish=${DOCS_HOST_PORT}:3002 \
--publish=3003:3003 \
--rm \
--tty \
${volumes} \
${DOCS_IMAGE} \
/entrypoint
EOF
await_build http://localhost:3003 &
if [ -n "${DEBUG}" ]; then
${cmd}
else
${cmd} 2>&1| sed \
-e '/Web Server is available at http:\/\/localhost:3003\/ (bind address 0.0.0.0)/ d' \
-e '/^hugo server/ d' \
-e '/fatal: not a git repository (or any parent up to mount point \/)/ d' \
-e '/Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set)./ d' \
-e "/Makefile:[0-9]*: warning: overriding recipe for target 'docs'/ d" \
-e "/docs.mk:[0-9]*: warning: ignoring old recipe for target 'docs'/ d" \
-e '/\/usr\/bin\/make -j 2 proxy hserver-docs HUGO_PORT=3003/ d' \
-e '/website-proxy/ d' \
-e '/rm -rf dist*/ d' \
-e '/Press Ctrl+C to stop/ d' \
-e '/make/ d' || echo
fi
;;
esac

View File

@@ -13,7 +13,7 @@ weight: 600
Besides the wide range of visualizations and data sources that are available immediately after you install Grafana, you can extend your Grafana experience with _plugins_.
You can [install]({{< relref "#install-a-plugin" >}}) one of the plugins built by the Grafana community, or [build one yourself]({{< relref "../../developers/plugins/" >}}).
You can [install]({{< relref "#install-a-plugin" >}}) one of the plugins built by the Grafana community, or [build one yourself](https://grafana.com/developers/plugin-tools).
Grafana supports three types of plugins: [panels](/grafana/plugins?type=panel), [data sources](/plugins?type=datasource), and [apps](/grafana/plugins?type=app).
@@ -163,7 +163,7 @@ Grafana also writes an error message to the server log:
WARN[05-26|12:00:00] Some plugin scanning errors were found errors="plugin '<plugin id>' is unsigned, plugin '<plugin id>' has an invalid signature"
```
If you are a plugin developer and want to know how to sign your plugin, refer to [Sign a plugin]({{< relref "../../developers/plugins/sign-a-plugin/" >}}).
If you are a plugin developer and want to know how to sign your plugin, refer to [Sign a plugin](https://grafana.com/developers/plugin-tools/publish-a-plugin/sign-a-plugin).
| Signature status | Description |
| ------------------ | ------------------------------------------------------------------------------- |

View File

@@ -61,7 +61,7 @@ Currently we do not provide any scripts/manifests for configuring Grafana. Rathe
| --------- | -------------------------------------------------------------------------------------------------------------- |
| Puppet | [https://forge.puppet.com/puppet/grafana](https://forge.puppet.com/puppet/grafana) |
| Ansible | [https://github.com/cloudalchemy/ansible-grafana](https://github.com/cloudalchemy/ansible-grafana) |
| Chef | [https://github.com/JonathanTron/chef-grafana](https://github.com/JonathanTron/chef-grafana) |
| Chef | [https://github.com/sous-chefs/chef-grafana](https://github.com/sous-chefs/chef-grafana) |
| Saltstack | [https://github.com/salt-formulas/salt-formula-grafana](https://github.com/salt-formulas/salt-formula-grafana) |
| Jsonnet | [https://github.com/grafana/grafonnet-lib/](https://github.com/grafana/grafonnet-lib/) |
@@ -355,8 +355,8 @@ When Grafana starts, it updates/inserts all dashboards available in the configur
By default, Grafana deletes dashboards in the database if the file is removed. You can disable this behavior using the `disableDeletion` setting.
> **Note:** Provisioning allows you to overwrite existing dashboards
> which leads to problems if you re-use settings that are supposed to be unique.
> Be careful not to re-use the same `title` multiple times within a folder
> which leads to problems if you reuse settings that are supposed to be unique.
> Be careful not to reuse the same `title` multiple times within a folder
> or `uid` within the same installation as this will cause weird behaviors.
### Provision folders structure from filesystem to Grafana

View File

@@ -10,7 +10,9 @@ weight: 80
# RBAC permissions, actions, and scopes
> **Note:** Available in [Grafana Enterprise]({{< relref "../../../../introduction/grafana-enterprise/" >}}) and [Grafana Cloud Advanced](/docs/grafana-cloud).
{{% admonition type="note" %}}
Available in [Grafana Enterprise]({{< relref "../../../../introduction/grafana-enterprise/" >}}) and [Grafana Cloud Advanced](/docs/grafana-cloud).
{{% /admonition %}}
A permission is comprised of an action and a scope. When creating a custom role, consider the actions the user can perform and the resource(s) on which they can perform those actions.
@@ -23,128 +25,129 @@ To learn more about the Grafana resources to which you can apply RBAC, refer to
The following list contains role-based access control actions.
| Action | Applicable scope | Description |
| ------------------------------------ | --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `alert.instances.external:read` | `datasources:*`<br>`datasources:uid:*` | Read alerts and silences in data sources that support alerting. |
| `alert.instances.external:write` | `datasources:*`<br>`datasources:uid:*` | Manage alerts and silences in data sources that support alerting. |
| `alert.instances:create` | n/a | Create silences in the current organization. |
| `alert.instances:read` | n/a | Read alerts and silences in the current organization. |
| `alert.instances:write` | n/a | Update and expire silences in the current organization. |
| `alert.notifications.external:read` | `datasources:*`<br>`datasources:uid:*` | Read templates, contact points, notification policies, and mute timings in data sources that support alerting. |
| `alert.notifications.external:write` | `datasources:*`<br>`datasources:uid:*` | Manage templates, contact points, notification policies, and mute timings in data sources that support alerting. |
| `alert.notifications:write` | n/a | Manage templates, contact points, notification policies, and mute timings in the current organization. |
| `alert.notifications:read` | n/a | Read all templates, contact points, notification policies, and mute timings in the current organization. |
| `alert.rules.external:read` | `datasources:*`<br>`datasources:uid:*` | Read alert rules in data sources that support alerting (Prometheus, Mimir, and Loki) |
| `alert.rules.external:write` | `datasources:*`<br>`datasources:uid:*` | Create, update, and delete alert rules in data sources that support alerting (Mimir and Loki). |
| `alert.rules:create` | `folders:*`<br>`folders:uid:*` | Create Grafana alert rules in a folder. Combine this permission with `folders:read` in a scope that includes the folder and `datasources:query` in the scope of data sources the user can query. |
| `alert.rules:delete` | `folders:*`<br>`folders:uid:*` | Delete Grafana alert rules in a folder. Combine this permission with `folders:read` in a scope that includes the folder and `datasources:query` in the scope of data sources the user can query. |
| `alert.rules:read` | `folders:*`<br>`folders:uid:*` | Read Grafana alert rules in a folder. Combine this permission with `folders:read` in a scope that includes the folder and `datasources:query` in the scope of data sources the user can query. |
| `alert.rules:write` | `folders:*`<br>`folders:uid:*` | Update Grafana alert rules in a folder. Combine this permission with `folders:read` in a scope that includes the folder and `datasources:query` in the scope of data sources the user can query. |
| `alert.provisioning:read` | n/a | Read all Grafana alert rules, notification policies, etc via provisioning API. Permissions to folders and datasource are not required. |
| `alert.provisioning:write` | n/a | Update all Grafana alert rules, notification policies, etc via provisioning API. Permissions to folders and datasource are not required. |
| `annotations:create` | `annotations:*`<br>`annotations:type:*` | Create annotations. |
| `annotations:delete` | `annotations:*`<br>`annotations:type:*` | Delete annotations. |
| `annotations:read` | `annotations:*`<br>`annotations:type:*` | Read annotations and annotation tags. |
| `annotations:write` | `annotations:*`<br>`annotations:type:*` | Update annotations. |
| `apikeys:create` | n/a | Create API keys. |
| `apikeys:read` | `apikeys:*`<br>`apikeys:id:*` | Read API keys. |
| `apikeys:delete` | `apikeys:*`<br>`apikeys:id:*` | Delete API keys. |
| `dashboards:create` | `folders:*`<br>`folders:uid:*` | Create dashboards in one or more folders. |
| `dashboards:delete` | `dashboards:*`<br>`dashboards:uid:*`<br>`folders:*`<br>`folders:uid:*` | Delete one or more dashboards. |
| `dashboards.insights:read` | n/a | Read dashboard insights data and see presence indicators. |
| `dashboards.permissions:read` | `dashboards:*`<br>`dashboards:uid:*`<br>`folders:*`<br>`folders:uid:*` | Read permissions for one or more dashboards. |
| `dashboards.permissions:write` | `dashboards:*`<br>`dashboards:uid:*`<br>`folders:*`<br>`folders:uid:*` | Update permissions for one or more dashboards. |
| `dashboards:read` | `dashboards:*`<br>`dashboards:uid:*`<br>`folders:*`<br>`folders:uid:*` | Read one or more dashboards. |
| `dashboards:write` | `dashboards:*`<br>`dashboards:uid:*`<br>`folders:*`<br>`folders:uid:*` | Update one or more dashboards. |
| `datasources.caching:read` | `datasources:*`<br>`datasources:uid:*` | Read data source query caching settings. |
| `datasources.caching:write` | `datasources:*`<br>`datasources:uid:*` | Update data source query caching settings. |
| `datasources:create` | n/a | Create data sources. |
| `datasources:delete` | `datasources:*`<br>`datasources:uid:*` | Delete data sources. |
| `datasources:explore` | n/a | Enable access to the **Explore** tab. |
| `datasources.id:read` | `datasources:*`<br>`datasources:uid:*` | Read data source IDs. |
| `datasources.insights:read` | n/a | Read data sources insights data. |
| `datasources.permissions:read` | `datasources:*`<br>`datasources:uid:*` | List data source permissions. |
| `datasources.permissions:write` | `datasources:*`<br>`datasources:uid:*` | Update data source permissions. |
| `datasources:query` | `datasources:*`<br>`datasources:uid:*` | Query data sources. |
| `datasources:read` | `datasources:*`<br>`datasources:uid:*` | List data sources. |
| `datasources:write` | `datasources:*`<br>`datasources:uid:*` | Update data sources. |
| `folders.permissions:read` | `folders:*`<br>`folders:uid:*` | Read permissions for one or more folders. |
| `folders.permissions:write` | `folders:*`<br>`folders:uid:*` | Update permissions for one or more folders. |
| `folders:create` | n/a | Create folders. |
| `folders:delete` | `folders:*`<br>`folders:uid:*` | Delete one or more folders. |
| `folders:read` | `folders:*`<br>`folders:uid:*` | Read one or more folders. |
| `folders:write` | `folders:*`<br>`folders:uid:*` | Update one or more folders. |
| `ldap.config:reload` | n/a | Reload the LDAP configuration. |
| `ldap.status:read` | n/a | Verify the availability of the LDAP server or servers. |
| `ldap.user:read` | n/a | Read users via LDAP. |
| `ldap.user:sync` | n/a | Sync users via LDAP. |
| `licensing.reports:read` | n/a | Get custom permission reports. |
| `licensing:delete` | n/a | Delete the license token. |
| `licensing:read` | n/a | Read licensing information. |
| `licensing:write` | n/a | Update the license token. |
| `org.users:write` | `users:*` <br> `users:id:*` | Update the organization role (`Viewer`, `Editor`, or `Admin`) of a user. |
| `org.users:add` | `users:*` | Add a user to an organization or invite a new user to an organization. |
| `org.users:read` | `users:*` <br> `users:id:*` | Get user profiles within an organization. |
| `org.users:remove` | `users:*` <br> `users:id:*` | Remove a user from an organization. |
| `org:create` | n/a | Create an organization. |
| `orgs.preferences:read` | `orgs:*` <br> `orgs:id:*` | Read organization preferences. |
| `orgs.preferences:write` | `orgs:*` <br> `orgs:id:*` | Update organization preferences. |
| `orgs.quotas:read` | `orgs:*` <br> `orgs:id:*` | Read organization quotas. |
| `orgs.quotas:write` | `orgs:*` <br> `orgs:id:*` | Update organization quotas. |
| `orgs:delete` | `orgs:*` <br> `orgs:id:*` | Delete one or more organizations. |
| `orgs:read` | `orgs:*` <br> `orgs:id:*` | Read one or more organizations. |
| `orgs:write` | `orgs:*` <br> `orgs:id:*` | Update one or more organizations. |
| `plugins.app:access` | `plugins:*` <br> `plugins:id:*` | Access one or more application plugins (still enforcing the organization role) |
| `plugins:install` | n/a | Install and uninstall plugins. |
| `plugins:write` | `plugins:*` <br> `plugins:id:*` | Edit settings for one or more plugins. |
| `provisioning:reload` | `provisioners:*` | Reload provisioning files. To find the exact scope for specific provisioner, see [Scope definitions]({{< relref "#scope-definitions" >}}). |
| `reports:create` | n/a | Create reports. |
| `reports:write` | `reports:*` <br> `reports:id:*` | Update reports. |
| `reports.settings:read` | n/a | Read report settings. |
| `reports.settings:write` | n/a | Update report settings. |
| `reports:delete` | `reports:*` <br> `reports:id:*` | Delete reports. |
| `reports:read` | `reports:*` | List all available reports or get a specific report. |
| `reports:send` | `reports:*` | Send a report email. |
| `roles:delete` | `permissions:type:delegate` | Delete a custom role. |
| `roles:read` | `roles:*` <br> `roles:uid:*` | List roles and read a specific with its permissions. |
| `roles:write` | `permissions:type:delegate` | Create or update a custom role. |
| `roles:write` | `permissions:type:escalate` | Reset basic roles to their default permissions. |
| `server.stats:read` | n/a | Read Grafana instance statistics. |
| `serviceaccounts:write` | `serviceaccounts:*` | Create Grafana service accounts. |
| `serviceaccounts:create` | n/a | Update Grafana service accounts. |
| `serviceaccounts:delete` | `serviceaccounts:*` | Delete Grafana service accounts. |
| `serviceaccounts:read` | `serviceaccounts:*` | Read Grafana service accounts. |
| `serviceaccounts.permissions:write` | `serviceaccounts:*` | Update Grafana service account permissions to control who can do what with the service account. |
| `serviceaccounts.permissions:read` | `serviceaccounts:*` | Read Grafana service account permissions to see who can do what with the service account. |
| `settings:read` | `settings:*`<br>`settings:auth.saml:*`<br>`settings:auth.saml:enabled` (property level) | Read the [Grafana configuration settings]({{< relref "../../../../setup-grafana/configure-grafana/" >}}) |
| `settings:write` | `settings:*`<br>`settings:auth.saml:*`<br>`settings:auth.saml:enabled` (property level) | Update any Grafana configuration settings that can be [updated at runtime]({{< relref "../../../../setup-grafana/configure-grafana/settings-updates-at-runtime" >}}). |
| `status:accesscontrol` | `services:accesscontrol` | Get access-control enabled status. |
| `teams.permissions:read` | `teams:*`<br>`teams:id:*` | Read members and External Group Synchronization setup for teams. |
| `teams.permissions:write` | `teams:*`<br>`teams:id:*` | Add, remove and update members and manage External Group Synchronization setup for teams. |
| `teams.roles:add` | `permissions:type:delegate` | Assign a role to a team. |
| `teams.roles:read` | `teams:*` | List roles assigned directly to a team. |
| `teams.roles:remove` | `permissions:type:delegate` | Unassign a role from a team. |
| `teams:create` | n/a | Create teams. |
| `teams:delete` | `teams:*`<br>`teams:id:*` | Delete one or more teams. |
| `teams:read` | `teams:*`<br>`teams:id:*` | Read one or more teams and team preferences. |
| `teams:write` | `teams:*`<br>`teams:id:*` | Update one or more teams and team preferences. |
| `users.authtoken:read` | `global.users:*` <br> `global.users:id:*` | List authentication tokens that are assigned to a user. |
| `users.authtoken:write` | `global.users:*` <br> `global.users:id:*` | Update authentication tokens that are assigned to a user. |
| `users.password:write` | `global.users:*` <br> `global.users:id:*` | Update a users password. |
| `users.permissions:read` | `users:*` | List permissions of a user. |
| `users.permissions:write` | `global.users:*` <br> `global.users:id:*` | Update a users organization-level permissions. |
| `users.quotas:read` | `global.users:*` <br> `global.users:id:*` | List a users quotas. |
| `users.quotas:write` | `global.users:*` <br> `global.users:id:*` | Update a users quotas. |
| `users.roles:add` | `permissions:type:delegate` | Assign a role to a user or a service account. |
| `users.roles:read` | `users:*` | List roles assigned directly to a user or a service account. |
| `users.roles:remove` | `permissions:type:delegate` | Unassign a role from a user or a service account. |
| `users:create` | n/a | Create a user. |
| `users:delete` | `global.users:*` <br> `global.users:id:*` | Delete a user. |
| `users:disable` | `global.users:*` <br> `global.users:id:*` | Disable a user. |
| `users:enable` | `global.users:*` <br> `global.users:id:*` | Enable a user. |
| `users:logout` | `global.users:*` <br> `global.users:id:*` | Sign out a user. |
| `users:read` | `global.users:*` | Read or search user profiles. |
| `users:write` | `global.users:*` <br> `global.users:id:*` | Update a users profile. |
| Action | Applicable scope | Description |
| ------------------------------------ | --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `alert.instances.external:read` | `datasources:*`<br>`datasources:uid:*` | Read alerts and silences in data sources that support alerting. |
| `alert.instances.external:write` | `datasources:*`<br>`datasources:uid:*` | Manage alerts and silences in data sources that support alerting. |
| `alert.instances:create` | n/a | Create silences in the current organization. |
| `alert.instances:read` | n/a | Read alerts and silences in the current organization. |
| `alert.instances:write` | n/a | Update and expire silences in the current organization. |
| `alert.notifications.external:read` | `datasources:*`<br>`datasources:uid:*` | Read templates, contact points, notification policies, and mute timings in data sources that support alerting. |
| `alert.notifications.external:write` | `datasources:*`<br>`datasources:uid:*` | Manage templates, contact points, notification policies, and mute timings in data sources that support alerting. |
| `alert.notifications:write` | n/a | Manage templates, contact points, notification policies, and mute timings in the current organization. |
| `alert.notifications:read` | n/a | Read all templates, contact points, notification policies, and mute timings in the current organization. |
| `alert.rules.external:read` | `datasources:*`<br>`datasources:uid:*` | Read alert rules in data sources that support alerting (Prometheus, Mimir, and Loki) |
| `alert.rules.external:write` | `datasources:*`<br>`datasources:uid:*` | Create, update, and delete alert rules in data sources that support alerting (Mimir and Loki). |
| `alert.rules:create` | `folders:*`<br>`folders:uid:*` | Create Grafana alert rules in a folder and its subfolders. Combine this permission with `folders:read` in a scope that includes the folder and `datasources:query` in the scope of data sources the user can query. |
| `alert.rules:delete` | `folders:*`<br>`folders:uid:*` | Delete Grafana alert rules in a folder and its subfolders. Combine this permission with `folders:read` in a scope that includes the folder and `datasources:query` in the scope of data sources the user can query. |
| `alert.rules:read` | `folders:*`<br>`folders:uid:*` | Read Grafana alert rules in a folder and its subfolders. Combine this permission with `folders:read` in a scope that includes the folder and `datasources:query` in the scope of data sources the user can query. |
| `alert.rules:write` | `folders:*`<br>`folders:uid:*` | Update Grafana alert rules in a folder and its subfolders. Combine this permission with `folders:read` in a scope that includes the folder and `datasources:query` in the scope of data sources the user can query. |
| `alert.provisioning:read` | n/a | Read all Grafana alert rules, notification policies, etc via provisioning API. Permissions to folders and datasource are not required. |
| `alert.provisioning:write` | n/a | Update all Grafana alert rules, notification policies, etc via provisioning API. Permissions to folders and datasource are not required. |
| `annotations:create` | `annotations:*`<br>`annotations:type:*` | Create annotations. |
| `annotations:delete` | `annotations:*`<br>`annotations:type:*` | Delete annotations. |
| `annotations:read` | `annotations:*`<br>`annotations:type:*` | Read annotations and annotation tags. |
| `annotations:write` | `annotations:*`<br>`annotations:type:*` | Update annotations. |
| `apikeys:create` | n/a | Create API keys. |
| `apikeys:read` | `apikeys:*`<br>`apikeys:id:*` | Read API keys. |
| `apikeys:delete` | `apikeys:*`<br>`apikeys:id:*` | Delete API keys. |
| `dashboards:create` | `folders:*`<br>`folders:uid:*` | Create dashboards in one or more folders and their subfolders. |
| `dashboards:delete` | `dashboards:*`<br>`dashboards:uid:*`<br>`folders:*`<br>`folders:uid:*` | Delete one or more dashboards. |
| `dashboards.insights:read` | n/a | Read dashboard insights data and see presence indicators. |
| `dashboards.permissions:read` | `dashboards:*`<br>`dashboards:uid:*`<br>`folders:*`<br>`folders:uid:*` | Read permissions for one or more dashboards. |
| `dashboards.permissions:write` | `dashboards:*`<br>`dashboards:uid:*`<br>`folders:*`<br>`folders:uid:*` | Update permissions for one or more dashboards. |
| `dashboards:read` | `dashboards:*`<br>`dashboards:uid:*`<br>`folders:*`<br>`folders:uid:*` | Read one or more dashboards. |
| `dashboards:write` | `dashboards:*`<br>`dashboards:uid:*`<br>`folders:*`<br>`folders:uid:*` | Update one or more dashboards. |
| `dashboards.public:write` | `dashboards:*`<br>`dashboards:uid:*` | Write public dashboard configuration. |
| `datasources.caching:read` | `datasources:*`<br>`datasources:uid:*` | Read data source query caching settings. |
| `datasources.caching:write` | `datasources:*`<br>`datasources:uid:*` | Update data source query caching settings. |
| `datasources:create` | n/a | Create data sources. |
| `datasources:delete` | `datasources:*`<br>`datasources:uid:*` | Delete data sources. |
| `datasources:explore` | n/a | Enable access to the **Explore** tab. |
| `datasources.id:read` | `datasources:*`<br>`datasources:uid:*` | Read data source IDs. |
| `datasources.insights:read` | n/a | Read data sources insights data. |
| `datasources.permissions:read` | `datasources:*`<br>`datasources:uid:*` | List data source permissions. |
| `datasources.permissions:write` | `datasources:*`<br>`datasources:uid:*` | Update data source permissions. |
| `datasources:query` | `datasources:*`<br>`datasources:uid:*` | Query data sources. |
| `datasources:read` | `datasources:*`<br>`datasources:uid:*` | List data sources. |
| `datasources:write` | `datasources:*`<br>`datasources:uid:*` | Update data sources. |
| `folders.permissions:read` | `folders:*`<br>`folders:uid:*` | Read permissions for one or more folders and their subfolders. |
| `folders.permissions:write` | `folders:*`<br>`folders:uid:*` | Update permissions for one or more folders and their subfolders. |
| `folders:create` | n/a | Create folders in the root level. If granted together with `folders:write`, also allows creating subfolders under all folders that the user can update. |
| `folders:delete` | `folders:*`<br>`folders:uid:*` | Delete one or more folders and their subfolders. |
| `folders:read` | `folders:*`<br>`folders:uid:*` | Read one or more folders and their subfolders. |
| `folders:write` | `folders:*`<br>`folders:uid:*` | Update one or more folders and their subfolders. If granted together with `folders:create` permission, also allows creating subfolders under these folders. |
| `ldap.config:reload` | n/a | Reload the LDAP configuration. |
| `ldap.status:read` | n/a | Verify the availability of the LDAP server or servers. |
| `ldap.user:read` | n/a | Read users via LDAP. |
| `ldap.user:sync` | n/a | Sync users via LDAP. |
| `licensing.reports:read` | n/a | Get custom permission reports. |
| `licensing:delete` | n/a | Delete the license token. |
| `licensing:read` | n/a | Read licensing information. |
| `licensing:write` | n/a | Update the license token. |
| `org.users:write` | `users:*` <br> `users:id:*` | Update the organization role (`Viewer`, `Editor`, or `Admin`) of a user. |
| `org.users:add` | `users:*` | Add a user to an organization or invite a new user to an organization. |
| `org.users:read` | `users:*` <br> `users:id:*` | Get user profiles within an organization. |
| `org.users:remove` | `users:*` <br> `users:id:*` | Remove a user from an organization. |
| `org:create` | n/a | Create an organization. |
| `orgs.preferences:read` | `orgs:*` <br> `orgs:id:*` | Read organization preferences. |
| `orgs.preferences:write` | `orgs:*` <br> `orgs:id:*` | Update organization preferences. |
| `orgs.quotas:read` | `orgs:*` <br> `orgs:id:*` | Read organization quotas. |
| `orgs.quotas:write` | `orgs:*` <br> `orgs:id:*` | Update organization quotas. |
| `orgs:delete` | `orgs:*` <br> `orgs:id:*` | Delete one or more organizations. |
| `orgs:read` | `orgs:*` <br> `orgs:id:*` | Read one or more organizations. |
| `orgs:write` | `orgs:*` <br> `orgs:id:*` | Update one or more organizations. |
| `plugins.app:access` | `plugins:*` <br> `plugins:id:*` | Access one or more application plugins (still enforcing the organization role) |
| `plugins:install` | n/a | Install and uninstall plugins. |
| `plugins:write` | `plugins:*` <br> `plugins:id:*` | Edit settings for one or more plugins. |
| `provisioning:reload` | `provisioners:*` | Reload provisioning files. To find the exact scope for specific provisioner, see [Scope definitions]({{< relref "#scope-definitions" >}}). |
| `reports:create` | n/a | Create reports. |
| `reports:write` | `reports:*` <br> `reports:id:*` | Update reports. |
| `reports.settings:read` | n/a | Read report settings. |
| `reports.settings:write` | n/a | Update report settings. |
| `reports:delete` | `reports:*` <br> `reports:id:*` | Delete reports. |
| `reports:read` | `reports:*` | List all available reports or get a specific report. |
| `reports:send` | `reports:*` | Send a report email. |
| `roles:delete` | `permissions:type:delegate` | Delete a custom role. |
| `roles:read` | `roles:*` <br> `roles:uid:*` | List roles and read a specific with its permissions. |
| `roles:write` | `permissions:type:delegate` | Create or update a custom role. |
| `roles:write` | `permissions:type:escalate` | Reset basic roles to their default permissions. |
| `server.stats:read` | n/a | Read Grafana instance statistics. |
| `serviceaccounts:write` | `serviceaccounts:*` | Create Grafana service accounts. |
| `serviceaccounts:create` | n/a | Update Grafana service accounts. |
| `serviceaccounts:delete` | `serviceaccounts:*` | Delete Grafana service accounts. |
| `serviceaccounts:read` | `serviceaccounts:*` | Read Grafana service accounts. |
| `serviceaccounts.permissions:write` | `serviceaccounts:*` | Update Grafana service account permissions to control who can do what with the service account. |
| `serviceaccounts.permissions:read` | `serviceaccounts:*` | Read Grafana service account permissions to see who can do what with the service account. |
| `settings:read` | `settings:*`<br>`settings:auth.saml:*`<br>`settings:auth.saml:enabled` (property level) | Read the [Grafana configuration settings]({{< relref "../../../../setup-grafana/configure-grafana/" >}}) |
| `settings:write` | `settings:*`<br>`settings:auth.saml:*`<br>`settings:auth.saml:enabled` (property level) | Update any Grafana configuration settings that can be [updated at runtime]({{< relref "../../../../setup-grafana/configure-grafana/settings-updates-at-runtime" >}}). |
| `status:accesscontrol` | `services:accesscontrol` | Get access-control enabled status. |
| `teams.permissions:read` | `teams:*`<br>`teams:id:*` | Read members and Team Sync setup for teams. |
| `teams.permissions:write` | `teams:*`<br>`teams:id:*` | Add, remove and update members and manage Team Sync setup for teams. |
| `teams.roles:add` | `permissions:type:delegate` | Assign a role to a team. |
| `teams.roles:read` | `teams:*` | List roles assigned directly to a team. |
| `teams.roles:remove` | `permissions:type:delegate` | Unassign a role from a team. |
| `teams:create` | n/a | Create teams. |
| `teams:delete` | `teams:*`<br>`teams:id:*` | Delete one or more teams. |
| `teams:read` | `teams:*`<br>`teams:id:*` | Read one or more teams and team preferences. |
| `teams:write` | `teams:*`<br>`teams:id:*` | Update one or more teams and team preferences. |
| `users.authtoken:read` | `global.users:*` <br> `global.users:id:*` | List authentication tokens that are assigned to a user. |
| `users.authtoken:write` | `global.users:*` <br> `global.users:id:*` | Update authentication tokens that are assigned to a user. |
| `users.password:write` | `global.users:*` <br> `global.users:id:*` | Update a users password. |
| `users.permissions:read` | `users:*` | List permissions of a user. |
| `users.permissions:write` | `global.users:*` <br> `global.users:id:*` | Update a users organization-level permissions. |
| `users.quotas:read` | `global.users:*` <br> `global.users:id:*` | List a users quotas. |
| `users.quotas:write` | `global.users:*` <br> `global.users:id:*` | Update a users quotas. |
| `users.roles:add` | `permissions:type:delegate` | Assign a role to a user or a service account. |
| `users.roles:read` | `users:*` | List roles assigned directly to a user or a service account. |
| `users.roles:remove` | `permissions:type:delegate` | Unassign a role from a user or a service account. |
| `users:create` | n/a | Create a user. |
| `users:delete` | `global.users:*` <br> `global.users:id:*` | Delete a user. |
| `users:disable` | `global.users:*` <br> `global.users:id:*` | Disable a user. |
| `users:enable` | `global.users:*` <br> `global.users:id:*` | Enable a user. |
| `users:logout` | `global.users:*` <br> `global.users:id:*` | Sign out a user. |
| `users:read` | `global.users:*` | Read or search user profiles. |
| `users:write` | `global.users:*` <br> `global.users:id:*` | Update a users profile. |
### Grafana OnCall action definitions (beta)
@@ -193,7 +196,7 @@ The following list contains role-based access control scopes.
| `apikeys:*`<br>`apikeys:id:*` | Restrict an action to a set of API keys. For example, `apikeys:*` matches any API key, `apikey:id:1` matches the API key whose id is `1`. |
| `dashboards:*`<br>`dashboards:uid:*` | Restrict an action to a set of dashboards. For example, `dashboards:*` matches any dashboard, and `dashboards:uid:1` matches the dashboard whose UID is `1`. |
| `datasources:*`<br>`datasources:uid:*` | Restrict an action to a set of data sources. For example, `datasources:*` matches any data source, and `datasources:uid:1` matches the data source whose UID is `1`. |
| `folders:*`<br>`folders:uid:*` | Restrict an action to a set of folders. For example, `folders:*` matches any folder, and `folders:uid:1` matches the folder whose UID is `1`. |
| `folders:*`<br>`folders:uid:*` | Restrict an action to a set of folders. For example, `folders:*` matches any folder, and `folders:uid:1` matches the folder whose UID is `1`. Note that permissions granted to a folder cascade down to subfolders located under it |
| `global.users:*` <br> `global.users:id:*` | Restrict an action to a set of global users. For example, `global.users:*` matches any user and `global.users:id:1` matches the user whose ID is `1`. |
| `orgs:*` <br> `orgs:id:*` | Restrict an action to a set of organizations. For example, `orgs:*` matches any organization and `orgs:id:1` matches the organization whose ID is `1`. |
| `permissions:type:delegate` | The scope is only applicable for roles associated with the Access Control itself and indicates that you can delegate your permissions only, or a subset of it, by creating a new role or making an assignment. |
@@ -207,3 +210,4 @@ The following list contains role-based access control scopes.
| `settings:*` | Restrict an action to a subset of settings. For example, `settings:*` matches all settings, `settings:auth.saml:*` matches all SAML settings, and `settings:auth.saml:enabled` matches the enable property on the SAML settings. |
| `teams:*` <br> `teams:id:*` | Restrict an action to a set of teams from an organization. For example, `teams:*` matches any team and `teams:id:1` matches the team whose ID is `1`. |
| `users:*` <br> `users:id:*` | Restrict an action to a set of users from an organization. For example, `users:*` matches any user and `users:id:1` matches the user whose ID is `1`. |
| `n/a` | `n/a` means not applicable. If an action has `n/a` specified for the scope, then the action does not require a scope. For example, the `teams:create` action does not require a scope and allows users to create teams. |

View File

@@ -15,7 +15,7 @@ labels:
products:
- enterprise
- oss
title: Stats and license
title: View server statistics and license
weight: 400
---
@@ -25,11 +25,11 @@ This setting contains information about tools that Grafana Server Admins can use
## View Grafana server settings
> Refer to [Role-based access control]({{< relref "../roles-and-permissions/access-control/" >}}) in Grafana Enterprise to understand how you can control access with RBAC permissions.
> Refer to [Role-based access control]({{< relref "../roles-and-permissions/access-control" >}}) in Grafana Enterprise to understand how you can control access with RBAC permissions.
If you are a Grafana server administrator, use the Settings tab to view the settings that are applied to your Grafana server via the [Configuration]({{< relref "../../setup-grafana/configure-grafana/#config-file-locations" >}}) file and any environmental variables.
If you are a Grafana server administrator, use the Settings tab to view the settings that are applied to your Grafana server via the [Configuration]({{< relref "../../setup-grafana/configure-grafana#configuration-file-location" >}}) file and any environmental variables.
> **Note:** Only Grafana server administrators can access the **Server Admin** menu. For more information about about administrative permissions, refer to [Roles and permissions]({{< relref "../roles-and-permissions/#grafana-server-administrators" >}}).
> **Note:** Only Grafana server administrators can access the **Server Admin** menu. For more information about about administrative permissions, refer to [Roles and permissions]({{< relref "../roles-and-permissions#grafana-server-administrators" >}}).
### View server settings
@@ -38,15 +38,15 @@ If you are a Grafana server administrator, use the Settings tab to view the sett
### Available settings
For a full list of server settings, refer to [Configuration]({{< relref "../../setup-grafana/configure-grafana/" >}}).
For a full list of server settings, refer to [Configuration]({{< relref "../../setup-grafana/configure-grafana#server" >}}).
## View Grafana server stats
> Refer to [Role-based access control]({{< relref "../roles-and-permissions/access-control/" >}}) in Grafana Enterprise to understand how you can control access with RBAC permissions.
> Refer to [Role-based access control]({{< relref "../roles-and-permissions/access-control" >}}) in Grafana Enterprise to understand how you can control access with RBAC permissions.
If you are a Grafana server admin, then you can view useful statistics about your Grafana server in the Stats & Licensing tab.
> **Note:** Only Grafana server administrators can access the **Server Admin** menu. For more information about about administrative permissions, refer to [Roles and permissions]({{< relref "../roles-and-permissions/#grafana-server-administrators" >}}).
> **Note:** Only Grafana server administrators can access the **Server Admin** menu. For more information about about administrative permissions, refer to [Roles and permissions]({{< relref "../roles-and-permissions#grafana-server-administrators" >}}).
### View server stats

View File

@@ -8,7 +8,7 @@ weight: 500
# Manage dashboard permissions
Dashboard and dasboard folder permissions enable you to grant a viewer the ability to edit and save dashboard changes, or limit an editor's permission to modify a dashboard.
Dashboard and dashboard folder permissions enable you to grant a viewer the ability to edit and save dashboard changes, or limit an editor's permission to modify a dashboard.
For more information about dashboard permissions, refer to [Dashboard permissions]({{< relref "../../roles-and-permissions/#dashboard-permissions" >}}).

View File

@@ -83,11 +83,11 @@ Configure alerting behavior in the absence of data using information in the foll
| No Data Option | Description |
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| No Data | Create a new alert `DatasourceNoData` with the name and UID of the alert rule, and UID of the datasource that returned no data as labels. |
| Alerting | Set alert rule state to `Alerting`. |
| Alerting | Set alert rule state to `Alerting`. This option will respect the configured **Evaluate for** pending period. |
| Ok | Set alert rule state to `Normal`. |
| Error or timeout option | Description |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| Alerting | Set alert rule state to `Alerting`. From Grafana 8.5, the alert rule waits for the entire duration for which the condition is true before firing. |
| OK | Set alert rule state to `Normal` |
| re | Error | Create a new alert `DatasourceError` with the name and UID of the alert rule, and UID of the datasource that returned no data as labels. |
| Error or timeout option | Description |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| Error | Create a new alert `DatasourceError` with the name and UID of the alert rule, and UID of the datasource that returned no data as labels. |
| Alerting | Set alert rule state to `Alerting`. This option will respect the configured **Evaluate for** pending period. |
| OK | Set alert rule state to `Normal` |

View File

@@ -53,11 +53,11 @@ Alert summary:
You can use any of the following built-in template options to embed custom templates.
| Name | Notes |
| ----------------------- | ------------------------------------------------------------- |
| `default.title` | Displays high-level status information. |
| `default.message` | Provides a formatted summary of firing and resolved alerts. |
| `teams.default.message` | Similar to `default.messsage`, formatted for Microsoft Teams. |
| Name | Notes |
| ----------------------- | ------------------------------------------------------------ |
| `default.title` | Displays high-level status information. |
| `default.message` | Provides a formatted summary of firing and resolved alerts. |
| `teams.default.message` | Similar to `default.message`, formatted for Microsoft Teams. |
### HTML in notification templates

View File

@@ -1,8 +1,8 @@
---
aliases:
- /docs/grafana/latest/alerting/contact-points/
- /docs/grafana/latest/alerting/unified-alerting/contact-points/
- /docs/grafana/latest/alerting/fundamentals/contact-points/contact-point-types/
- ../contact-points/
- ../unified-alerting/contact-points/
- contact-point-types/
description: Create or edit contact point
keywords:
- grafana

View File

@@ -23,7 +23,7 @@ Grafana managed alerts query the following backend data sources that have alerti
- built-in data sources or those developed and maintained by Grafana: `Graphite`, `Prometheus`, `Loki`, `InfluxDB`, `Elasticsearch`,
`Google Cloud Monitoring`, `Cloudwatch`, `Azure Monitor`, `MySQL`, `PostgreSQL`, `MSSQL`, `OpenTSDB`, `Oracle`, and `Azure Monitor`
- community developed backend data sources with alerting enabled (`backend` and `alerting` properties are set in the [plugin.json]({{< relref "/docs/grafana/latest/developers/plugins/metadata" >}}))
- community developed backend data sources with alerting enabled (`backend` and `alerting` properties are set in the [plugin.json](https://grafana.com/developers/plugin-tools/reference-plugin-json)
### Metrics from the alerting engine

View File

@@ -20,7 +20,7 @@ A mute timing is a recurring interval of time when no new notifications for a po
Similar to silences, mute timings do not prevent alert rules from being evaluated, nor do they stop alert instances from being shown in the user interface. They only prevent notifications from being created.
You can configure Grafana managed mute timings as well as mute timings for an [external Alertmanager data source]({{< relref "/docs/grafana/latest/datasources/alertmanager" >}}). For more information, refer to [Alertmanager documentation]({{< relref "/docs/grafana/latest/alerting/manage-notifications/alertmanager" >}}).
You can configure Grafana managed mute timings as well as mute timings for an external Alertmanager.
## Mute timings vs silences

View File

@@ -20,16 +20,21 @@ longer supported. We refer to these as [Differences]({{< relref "#differences" >
2. Read and write access to legacy dashboard alerts and Grafana alerts are governed by the permissions of the folders storing them. During migration, legacy dashboard alert permissions are matched to the new rules permissions as follows:
- If alert's dashboard has permissions, it will create a folder named like `Migrated {"dashboardUid": "UID", "panelId": 1, "alertId": 1}` to match permissions of the dashboard (including the inherited permissions from the folder).
- If there are no dashboard permissions and the dashboard is under a folder, then the rule is linked to this folder and inherits its permissions.
- If there are no dashboard permissions and the dashboard is under the General folder, then the rule is linked to the `General Alerting` folder, and the rule inherits the default permissions.
- If there are dashboard permissions, a folder named `Migrated {"dashboardUid": "UID", "panelId": 1, "alertId": 1}` is created to match the permissions of the dashboard (including the inherited permissions from the folder).
- If there are no dashboard permissions and the dashboard is in a folder, then the rule is linked to this folder and inherits its permissions.
- If there are no dashboard permissions and the dashboard is in the General folder, then the rule is linked to the `General Alerting` folder and the rule inherits the default permissions.
3. Since there is no `Keep Last State` option for [`No Data`]({{< relref "../alerting-rules/create-grafana-managed-rule/#no-data--error-handling" >}}) in Grafana Alerting, this option becomes `NoData` during the legacy rules migration. Option "Keep Last State" for [`Error handling`]({{< relref "../alerting-rules/create-grafana-managed-rule/#no-data--error-handling" >}}) is migrated to a new option `Error`. To match the behavior of the `Keep Last State`, in both cases, during the migration Grafana automatically creates a silence for each alert rule with a duration of 1 year.
3. `NoData` and `Error` settings are migrated as is to the corresponding settings in Grafana Alerting, except in two situations:
3.1. As there is no `Keep Last State` option for `No Data` in Grafana Alerting, this option becomes `NoData`. The `Keep Last State` option for `Error` is migrated to a new option `Error`. To match the behavior of the `Keep Last State`, in both cases, during the migration Grafana automatically creates a silence for each alert rule with a duration of 1 year.
3.2. Due to lack of validation, legacy alert rules imported via JSON or provisioned along with dashboards can contain arbitrary values for `NoData` and [`Error`](/docs/sources/alerting/alerting-rules/create-grafana-managed-rule.md#configure-no-data-and-error-handling). In this situation, Grafana will use the default setting: `NoData` for No data, and `Error` for Error.
4. Notification channels are migrated to an Alertmanager configuration with the appropriate routes and receivers. Default notification channels are added as contact points to the default route. Notification channels not associated with any Dashboard alert go to the `autogen-unlinked-channel-recv` route.
5. Unlike legacy dashboard alerts where images in notifications are enabled per contact point, images in notifications for Grafana Alerting must be enabled in the Grafana configuration, either in the configuration file or environment variables, and are enabled for either all or no contact points. Refer to [images in notifications](https://grafana.com/docs/grafana/latest/alerting/manage-notifications/images-in-notifications/).
6. Grafana Alerting does not support pausing the evaluation of alert rules. After migration, all paused alert rules will become active, which may cause unexpected notifications to be sent.
5. Unlike legacy dashboard alerts where images in notifications are enabled per contact point, images in notifications for Grafana Alerting must be enabled in the Grafana configuration, either in the configuration file or environment variables, and are enabled for either all or no contact points. Refer to [images in notifications]({{< relref "../manage-notifications/images-in-notifications" >}}).
6. The JSON format for webhook notifications has changed in Grafana Alerting and uses the format from [Prometheus Alertmanager](https://prometheus.io/docs/alerting/latest/configuration/#webhook_config).
## Limitations

View File

@@ -27,7 +27,7 @@ Since gossiping of notifications and silences uses both TCP and UDP port `9094`,
1. In your custom configuration file ($WORKING_DIR/conf/custom.ini), go to the `[unified_alerting]` section.
2. Set `[ha_peers]` to the number of hosts for each Grafana instance in the cluster (using a format of host:port), for example, `ha_peers=10.0.0.5:9094,10.0.0.6:9094,10.0.0.7:9094`.
You must have at least one (1) Grafana instance added to the [`[ha_peer]` section.
You must have at least one (1) Grafana instance added to the `ha_peers` section.
3. Set `[ha_listen_address]` to the instance IP address using a format of `host:port` (or the [Pod's](https://kubernetes.io/docs/concepts/workloads/pods/) IP in the case of using Kubernetes).
By default, it is set to listen to all interfaces (`0.0.0.0`).

View File

@@ -66,7 +66,7 @@ groups:
# <string, required> which query should be used for the condition
condition: A
# <list, required> list of query objects that should be executed on each
# evaluation - should be obtained trough the API
# evaluation - should be obtained through the API
data:
- refId: A
datasourceUid: '__expr__'

View File

@@ -110,7 +110,7 @@ You cannot edit resources provisioned via Terraform from the UI. This ensures th
**Note:**
You can re-use the same templates across many contact points. In the example above, a shared template ie embedded using the statement `{{ template “Alert Instance Template” . }}`
You can reuse the same templates across many contact points. In the example above, a shared template ie embedded using the statement `{{ template “Alert Instance Template” . }}`
This fragment can then be managed separately in Terraform:

View File

@@ -1,7 +0,0 @@
---
title: Copyright notice
---
# Copyright notice
Copyright &#169; 2021 Raintank, Inc. dba Grafana Labs. All Rights Reserved.

View File

@@ -96,7 +96,7 @@ recent_users_age = 10m
> **Note:** Available in [Grafana Enterprise]({{< relref "../../introduction/grafana-enterprise/" >}}) version 7.0 and later, and [Grafana Cloud Pro and Advanced](/docs/grafana-cloud/).
In the search view, you can use insights data to help you find most-used, broken, and unused dashbaords.
In the search view, you can use insights data to help you find most-used, broken, and unused dashboards.
You can sort the dashboards by:

View File

@@ -14,85 +14,124 @@ weight: 600
# Annotate visualizations
Annotations provide a way to mark points on the graph with rich events. When you hover over an annotation
you can get event description and event tags. The text field can include links to other systems with more detail.
Annotations provide a way to mark points on a visualization with rich events. They are visualized as vertical lines and icons on all graph panels. When you hover over an annotation, you can get event description and event tags. The text field can include links to other systems with more detail.
{{< figure src="/static/img/docs/v46/annotations.png" max-width="800px" >}}
## Native annotations
You can annotate visualizations in three ways:
Grafana comes with a native annotation store and the ability to add annotation events directly from the graph panel or via the [HTTP API]({{< relref "../../../developers/http_api/annotations/" >}}).
- Directly in the panel, using the [built-in annotations query](#built-in-query)
- Using the HTTP API
- Configuring annotation queries in the dashboard settings
### Add annotation
In the first two cases, you're creating new annotations, while in the last you're querying existing annotations from data sources. The built-in annotation query also supports this.
1. In the dashboard click on the Time series panel. A context menu will appear.
1. In the context menu click on **Add annotation**.
This page explains the first and third options; for information about using the HTTP API, refer to [Annotations API]({{< relref "../../../developers/http_api/annotations/" >}}).
Annotations are supported for the following visualization types:
- Time series
- State timeline
- Candlestick
## Create annotations in panels
Grafana comes with the ability to add annotation events directly from a panel using the [built-in annotation query](#built-in-query) that exists on all dashboards. Annotations that you create this way are stored in Grafana.
To add annotations directly in the panel, the built-in query must be enabled. Learn more in [Built-in query](#built-in-query)
### Add an annotation
To add an annotation, complete the following steps:
1. In the dashboard click the panel to which you're adding the annotation. A context menu will appear.
1. In the context menu, click **Add annotation**.
![Add annotation context menu](/static/img/docs/time-series-panel/time-series-annotations-context-menu.png)
1. Add an annotation description and tags(optional).
![Add annotation popover](/static/img/docs/time-series-panel/time-series-annotations-add-annotation.png)
1. Click save.
1. Add an annotation description and tags (optional).
1. Click **Save**.
Alternatively, to add an annotation, Ctrl/Cmd+Click on the Time series panel and the Add annotation popover will appear
Alternatively, to add an annotation, press Ctrl/Cmd and click the panel, and the **Add annotation** popover will appear.
### Add region annotation
### Add a region annotation
1. In the dashboard Ctrl/Cmd+click and drag on the Time series panel.
1. In the dashboard press Ctrl/Cmd and click and drag on the panel.
![Add annotation popover](/static/img/docs/time-series-panel/time-series-annotations-add-region-annotation.gif)
1. Add an annotation description and tags(optional).
1. Click save.
1. Add an annotation description and tags (optional).
1. Click **Save**.
### Edit annotation
### Edit an annotation
1. In the dashboard hover over an annotation indicator on the Time series panel.
1. In the dashboard, hover over an annotation indicator on the Time series panel.
<!--![Add annotation popover](/static/img/docs/time-series-panel/time-series-annotations-edit-annotation.gif)-->
1. Click on the pencil icon in the annotation tooltip.
1. Modify the description and/or tags.
1. Click save.
### Delete annotation
### Delete an annotation
1. In the dashboard hover over an annotation indicator on the Time series panel.
1. In the dashboard hover over an annotation indicator on a panel.
<!--![Add annotation popover](/static/img/docs/time-series-panel/time-series-annotations-edit-annotation.gif)-->
1. Click on the trash icon in the annotation tooltip.
### Built-in query
## Fetch annotations through dashboard settings
After you added an annotation they will still be visible. This is due to the built in annotation query that exists on all dashboards. This annotation query will
fetch all annotation events that originate from the current dashboard and show them on the panel where they were created. This includes alert state history annotations. You can
stop annotations from being fetched and drawn by opening the **Annotations** settings (via Dashboard cogs menu) and modifying the query named `Annotations & Alerts (Built-in)`.
In the dashboard settings, under **Annotations**, you can add new queries to fetch annotations using any data source, including the built-in data annotation data source. Annotation queries return events that can be visualized as event markers in graphs across the dashboard.
When you copy a dashboard using the **Save As** feature it will get a new dashboard id so annotations created on source dashboard will no longer be visible on the copy. You
can still show them if you add a new **Annotation Query** and filter by tags. But this only works if the annotations on the source dashboard had tags to filter by.
### Add new annotation queries
### Query by tag
To add a new annotation query to a dashboard, take the following steps:
You can create new queries to fetch annotations from the native annotation store via the `-- Grafana --` data source by setting _Filter by_ to `Tags`.
1. Click the dashboard settings (gear) icon in the dashboard header to open the settings menu.
1. Select **Annotations**.
1. Click **Add annotation query**.
If you've added a query before, the **+ New query** button is displayed.
1. Enter a name for the annotation query.
This name is given to the toggle (checkbox) that will allow you to enable/disable showing annotation events from this query.
1. Select the data source for the annotations.
1. If you don't want to use the annotation query right away, clear the **Enabled** checkbox.
1. If you don't want the annotation query toggle to be displayed in the dashboard, select the **Hidden** checkbox.
1. Select a color for the event markers.
1. Configure the query.
The annotation query options are different for each data source. For information about annotations in a specific data source, refer to the specific [data source]({{< relref "../../../datasources/" >}}) topic.
## Built-in query
After you add an annotation, they will still be visible. This is due to the built-in annotation query that exists on all dashboards. This annotation query will fetch all annotation events that originate from the current dashboard, which are stored in Grafana, and show them on the panel where they were created. This includes alert state history annotations.
To add annotations directly to the dashboard, this query must be enabled.
To confirm if the built-in query is enabled, take the following steps:
1. Click the dashboard settings (gear) icon in the dashboard header to open the dashboard settings menu.
1. Click **Annotations**.
1. Find the **Annotations & Alerts (Built-in)** query.
If it says **Disabled** before the name of the query, then you'll need to click the query name to open it and update the setting.
You can stop annotations from being fetched and drawn by taking the following steps:
1. Click the dashboard settings (gear) icon in the dashboard header to open the settings menu.
1. Click **Annotations**.
1. Find and click the **Annotations & Alerts (Built-in)** query to open it.
1. Click the **Enabled** toggle to turn it off.
When you copy a dashboard using the **Save As** feature it will get a new dashboard id, so annotations created on source dashboard will no longer be visible on the copy. You can still show them if you add a new **Annotation Query** and filter by tags. However, this only works if the annotations on the source dashboard had tags to filter by.
### Filter queries by tag
You can create new queries to fetch annotations from the built-in annotation query using the `-- Grafana --` data source by setting _Filter by_ to `Tags`.
Grafana v8.1 and later versions also support typeahead of existing tags, provide at least one tag.
For example, create an annotation query name `outages` and specify a tag `outage`. This query will show all annotations (from any dashboard or via API) with the `outage` tag. If multiple tags are defined in an annotation query, then Grafana will only show annotations matching all the tags. To modify the behavior, enable `Match any`, and Grafana will show annotations that contain any one of the tags you provided.
{{< figure src="/static/img/docs/annotations/annotations_typeahead_support-8-1-0.png" max-width="600px" >}}
{{< figure src="/media/docs/grafana/dashboards/screenshot-annotations-typeahead-support-10.0.png" max-width="600px" >}}
In Grafana v5.3+ it's possible to use template variables in the tag query. So if you have a dashboard showing stats for different services and a template variable that dictates which services to show, you can now use the same template variable in your annotation query to only show annotations for those services.
You can also use template variables in the tag query. This means if you have a dashboard showing stats for different services and a template variable that dictates which services to show, you can use the same template variable in your annotation query to only show annotations for those services.
{{< figure src="/static/img/docs/annotations/annotation_tag_filter_variable-8-1-0.png" max-width="600px" >}}
## Querying other data sources
Annotation events are fetched via annotation queries. To add a new annotation query to a dashboard
open the dashboard settings menu, then select `Annotations`. This will open the dashboard annotations
settings view. To create a new annotation query hit the `New` button.
<!--![](/static/img/docs/v50/annotation_new_query.png)-->
{{< figure src="/static/img/docs/v50/annotation_new_query.png" max-width="600px" >}}
Specify a name for the annotation query. This name is given to the toggle (checkbox) that will allow
you to enable/disable showing annotation events from this query. For example you might have two
annotation queries named `Deploys` and `Outages`. The toggle will allow you to decide what annotations
to show.
### Annotation query details
The annotation query options are different for each data source. For information about annotations in a specific data source, refer to the specific [data source]({{< relref "../../../datasources/" >}}) topic.
{{< figure src="/media/docs/grafana/dashboards/screenshot-annotation-tag-filter-variable-10.0.png" max-width="600px" >}}

View File

@@ -65,7 +65,7 @@ The query parameter `var-adhoc=key|=|value` applies the ad hoc filter configured
### Example
See [https://play.grafana.org/d/000000002/influxdb-templated?orgId=1&var-datacenter=America&var-host=All&var-summarize=1m&var-adhoc=datacenter%7C%3D%7CAmerica] - this passes the ad hoc filter variable `adhoc` with the filter value `datacenter = America`.
[This example in Grafana Play](https://play.grafana.org/d/000000002/influxdb-templated?orgId=1&var-datacenter=America&var-host=All&var-summarize=1m&var-adhoc=datacenter%7C%3D%7CAmerica) passes the ad hoc filter variable `adhoc` with the filter value `datacenter = America`.
## Controlling time range using the URL

View File

@@ -10,6 +10,10 @@ keywords:
- reporting
- export
- pdf
labels:
products:
- cloud
- enterprise
menuTitle: Reporting
title: Create and manage reports
weight: 85
@@ -26,7 +30,7 @@ Reporting enables you to automatically generate PDFs from any of your dashboards
{{< figure src="/static/img/docs/enterprise/reports_list_8.1.png" max-width="500px" >}}
-->
Any changes you make to a dashboard used in a report are reflected the next time the report is sent. For example, if you change the time range in the dashboard, then the time range in the report also changes.
Any changes you make to a dashboard used in a report are reflected the next time the report is sent. For example, if you change the time range in the dashboard, then the time range in the report also changes, unless you've configured a custom time range.
For information about recent improvements to the reporting UI, refer to [Grafana reporting: How we improved the UX in Grafana](https://grafana.com/blog/2022/06/29/grafana-reporting-how-we-improved-the-ux-in-grafana/).
@@ -68,6 +72,14 @@ Only organization administrators can create reports by default. You can customiz
- **Send test email:** To verify that the configuration works as expected. You can choose to send this email to the recipients configured for the report, or to a different set of email addresses only used for testing.
1. Preview and save the report.
### Save as draft
{{% admonition type="note" %}}
Available in [Grafana Enterprise]({{< relref "../../introduction/grafana-enterprise/" >}}) version 9.1.0 and later and [Grafana Cloud Pro and Advanced](/docs/grafana-cloud/).
{{% /admonition %}}
You can save a report as a draft at any point during the report creation or update process. You can save a report as a draft even if it's missing required fields. Also, the report won't be sent according to its schedule while it's a draft.
### Choose template variables
> **Note:** Available in [Grafana Enterprise]({{< relref "../../introduction/grafana-enterprise/" >}}) version 7.5 and later behind the `reportVariables` feature flag, Grafana Enterprise version 8.0 and later without a feature flag, and [Grafana Cloud Pro and Advanced](/docs/grafana-cloud/).

View File

@@ -25,13 +25,13 @@ This topic provides an overview of dashboard features and shortcuts, and describ
The dashboard user interface provides a number of features that you can use to customize the presentation of your data.
The following image and descriptions highlights all dashboards features.
The following image and descriptions highlight all dashboard features.
{{< figure src="/static/img/docs/v91/dashboard-features/dashboard-features.png" width="700px" >}}
- (1) **Grafana home**: Click the Grafana home icon to be redirected to the home page configured in the Grafana instance.
- (2) **Dashboard title**: When you click the dashboard title you can search for dashboard contained in the current folder.
- (3) **Share dashboard**: Use this option to share the current dashboard by link or snapshot. You can also export the dashboard definition from the share modal.
- (2) **Dashboard title**: When you click the dashboard title, you can search for dashboards contained in the current folder.
- (3) **Share dashboard**: Use this option to share the current dashboard using a link or snapshot. You can also export the dashboard definition from the share modal.
- (4) **Add a new panel**: Use this option to add a panel, dashboard row, or library panel to the current dashboard.
- (5) **Dashboard settings**: Use this option to change dashboard name, folder, and tags and manage variables and annotation queries. For more information about dashboard settings, refer to [Modify dashboard settings]({{< relref "../build-dashboards/modify-dashboard-settings/" >}}).
- (6) **Time picker dropdown**: Click to select relative time range options and set custom absolute time ranges.

View File

@@ -45,20 +45,19 @@ To see variable settings, navigate to **Dashboard Settings > Variables**. Click
Variables can be used in titles, descriptions, text panels, and queries. Queries with text that starts with `$` are templates. Not all panels will have template queries.
The following dashboards in Grafana Play provide examples of template variables.
The following dashboards in Grafana Play provide examples of template variables:
- [Elasticsearch Metrics](https://play.grafana.org/d/z8OZC66nk/elasticsearch-8-2-0-sample-flight-data?orgId=1) - Uses ad hoc filters, global variables, and a custom variable.
- [Graphite Templated Nested](https://play.grafana.org/d/000000056/graphite-templated-nested?orgId=1) - Uses query variables, chained query variables, an interval variable, and a repeated panel.
- [Influx DB Group By Variable](https://play.grafana.org/d/000000137/influxdb-group-by-variable?orgId=1) - Query variable, panel uses the variable results to group the metric data.
- [InfluxDB Raw Query Template Var](https://play.grafana.org/d/000000083/influxdb-raw-query-template-var?orgId=1) - Uses query variables, chained query variables, and an interval variable.
- [InfluxDB Server Monitoring](https://play.grafana.org/d/AAy9r_bmk/influxdb-server-monitoring?orgId=1) - Uses query variables, chained query variables, an interval variable, and an ad hoc filter.
- [Prometheus templating](https://play.grafana.org/d/000000063/prometheus-templating?orgId=1) - Uses chained query variables.
- [Template Redux](https://play.grafana.org/d/p-k6QtkGz/template-redux?orgId=1) - Uses query variables, chained query variables, ad hoc filters, an interval variable, a text box variable, a custom variable, and a data source variable.
- [Graphite Templated Nested](https://play.grafana.org/d/000000056/templated-dynamic-dashboard?orgId=1&var-app=backend&var-server=backend_01&var-server=backend_02&var-server=backend_03&var-server=backend_04&var-interval=1h) - Uses query variables, chained query variables, an interval variable, and a repeated panel.
- [Global variables and interpolation](https://play.grafana.org/d/HYaGDGIMk/templating-global-variables-and-interpolation?orgId=1&var-Server=A%27A%22A&var-Server=BB%5CB)
- [Elasticsearch Dummy Flight Data](https://play.grafana.org/d/z8OZC66nk/elasticsearch-8-2-0-sample-flight-data?orgId=1&var-Filters=Carrier%7C%3D%7CLogstash%20Airways&var-query0=) - Uses ad hoc filters.
- [Templating, repeated panels](https://play.grafana.org/d/000000025/templating-repeated-panels?orgId=1) - Two sets of repeated panels use query variables.
- [Templating showcase](https://play.grafana.org/d/000000091/templating-showcase?orgId=1) - Uses custom, query, chained query, and data source variables.
- [Templating value groups](https://play.grafana.org/d/000000024/templating-value-groups?orgId=1) - Uses query variable with value groups.
- [Template Redux](https://play.grafana.org/d/p-k6QtkGz/template-redux?orgId=1) - Uses query variables, chained query variables, an interval variable, a text box variable, a custom variable, and a data source variable.
- [Nested Variables Drilldown](https://play.grafana.org/d/testdata-nested-variables-drilldown/templating-nested-variables-drilldown?orgId=1&var-datacenter=A&var-server=AA&var-server=AC&var-pod=All)
## Variable best practices
- Variable drop-down lists are displayed in the order they are listed in the variable list in Dashboard settings.
- Put the variables that you will change often at the top, so they will be shown first (far left on the dashboard).
- By default, variables don't have a default value. This means that the topmost value in the drop-down is always preselected. If you want to pre-populate a variable with an empty value, you can use the following workaround in the variable settings:
1. Select the **Include All Option** checkbox.
2. In the **Custom all value** field, enter a value like `+`.

View File

@@ -247,13 +247,13 @@ Grafana has two built-in time range variables: `$__from` and `$__to`. They are c
> **Note:** This special formatting syntax is only available in Grafana 7.1.2+
| Syntax | Example result | Description |
| ------------------------ | ------------------------ | --------------------------------------------------------------------------------------------------------- |
| `${__from}` | 1594671549254 | Unix millisecond epoch |
| `${__from:date}` | 2020-07-13T20:19:09.254Z | No args, defaults to ISO 8601/RFC 3339 |
| `${__from:date:iso}` | 2020-07-13T20:19:09.254Z | ISO 8601/RFC 3339 |
| `${__from:date:seconds}` | 1594671549 | Unix seconds epoch |
| `${__from:date:YYYY-MM}` | 2020-07 | Any custom [date format](https://momentjs.com/docs/#/displaying/) that does not include the `:` character |
| Syntax | Example result | Description |
| ------------------------ | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `${__from}` | 1594671549254 | Unix millisecond epoch |
| `${__from:date}` | 2020-07-13T20:19:09.254Z | No args, defaults to ISO 8601/RFC 3339 |
| `${__from:date:iso}` | 2020-07-13T20:19:09.254Z | ISO 8601/RFC 3339 |
| `${__from:date:seconds}` | 1594671549 | Unix seconds epoch |
| `${__from:date:YYYY-MM}` | 2020-07 | Any custom [date format](https://momentjs.com/docs/#/displaying/) that does not include the `:` character. Uses browser time. Use `:date` or `:date:iso` for UTC |
The syntax above also works with `${__to}`.
@@ -569,7 +569,7 @@ demo.robustperception.io:9100
Using named capture groups, you can capture separate 'text' and 'value' parts from the options returned by the variable query. This allows the variable drop-down list to contain a friendly name for each value that can be selected.
For example, when querying the `node_hwmon_chip_names` Prometheus metric, the `chip_name` is a lot friendlier that the `chip` value. So the following variable query result:
For example, when querying the `node_hwmon_chip_names` Prometheus metric, the `chip_name` is a lot friendlier than the `chip` value. So the following variable query result:
```text
node_hwmon_chip_names{chip="0000:d7:00_0_0000:d8:00_0",chip_name="enp216s0f0np0"} 1

View File

@@ -2,6 +2,7 @@
aliases:
- data-sources/
- overview/
- ./features/datasources/
cascade:
labels:
products:
@@ -29,7 +30,7 @@ After you add and configure a data source, you can use it as an input for many o
This documentation describes how to manage data sources in general,
and how to configure or query the built-in data sources.
For other data sources, refer to the list of [datasource plugins](/grafana/plugins/).
To develop a custom plugin, refer to [Build a plugin]({{< relref "../developers/plugins/" >}}).
To develop a custom plugin, refer to [Build a plugin](https://grafana.com/developers/plugin-tools).
## Manage data sources

View File

@@ -129,6 +129,11 @@ The Azure documentation includes resources to help you learn KQL:
- [Tutorial: Use Kusto queries in Azure Monitor](https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/tutorial?pivots=azuremonitor)
- [SQL to Kusto cheat sheet](https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/sqlcheatsheet)
> **Implicit dashboard time range usage:** As of Grafana v9.4.12 and v10.0, all Azure Monitor Logs queries
> will use the specified dashboard or Explore time range by default.
> Any query making use of a time range explicitly specified in the query body will have their query
> executed against the intersection of the two time ranges. For more details on this change, refer to the [Azure Monitor Logs API documentation](https://learn.microsoft.com/en-us/rest/api/loganalytics/dataaccess/query/get?tabs=HTTP#uri-parameters).
This example query returns a virtual machine's CPU performance, averaged over 5ms time grains:
```kusto

View File

@@ -17,7 +17,7 @@ weight: 700
# InfluxDB data source
{{< docs/shared "influxdb/intro.md" >}}
{{< docs/shared lookup="influxdb/intro.md" source="grafana" version="<GRAFANA VERSION>" >}}
Grafana includes built-in support for InfluxDB.
This topic explains options, variables, querying, and other features specific to the InfluxDB data source, which include its [feature-rich code editor for queries and visual query builder]({{< relref "./query-editor/" >}}).

View File

@@ -220,7 +220,7 @@ The resulting table panel:
If you set the **Format** setting in the query editor to **Time series**, then the query must have a column named `time` that returns either a SQL datetime or any numeric datatype representing Unix epoch in seconds.
Result sets of time series queries must also be sorted by time for panels to properly visualize the result.
A time series query result is returned in a [wide data frame format]({{< relref "../../../developers/plugins/data-frames#wide-format" >}}).
A time series query result is returned in a [wide data frame format](https://grafana.com/developers/plugin-tools/introduction/data-frames#wide-format).
Any column except time or of type string transforms into value fields in the data frame query result.
Any string column transforms into field labels in the data frame query result.

View File

@@ -213,7 +213,7 @@ The resulting table panel:
If you set Format as to _Time series_, then the query must have a column named time that returns either a SQL datetime or any numeric datatype representing Unix epoch in seconds. In addition, result sets of time series queries must be sorted by time for panels to properly visualize the result.
A time series query result is returned in a [wide data frame format]({{< relref "../../developers/plugins/data-frames#wide-format" >}}). Any column except time or of type string transforms into value fields in the data frame query result. Any string column transforms into field labels in the data frame query result.
A time series query result is returned in a [wide data frame format](https://grafana.com/developers/plugin-tools/introduction/data-frames#wide-format). Any column except time or of type string transforms into value fields in the data frame query result. Any string column transforms into field labels in the data frame query result.
> For backward compatibility, there's an exception to the above rule for queries that return three columns including a string column named metric. Instead of transforming the metric column into field labels, it becomes the field name, and then the series name is formatted as the value of the metric column. See the example with the metric column below.

View File

@@ -24,17 +24,26 @@ Administrators can also [configure the data source via YAML]({{< relref "#provis
## OpenTSDB settings
To access OpenTSDB settings, hover your mouse over the **Configuration** (gear) icon, then click **Data Sources**, and then click the OpenTSDB data source.
To configure basic settings for the data source, complete the following steps:
| Name | Description |
| ------------------- | --------------------------------------------------------------------------------------- |
| **Name** | The data source name. This is how you refer to the data source in panels and queries. |
| **Default** | Default data source means that it will be pre-selected for new panels. |
| **URL** | The HTTP protocol, IP, and port of your OpenTSDB server (default port is usually 4242) |
| **Allowed cookies** | List the names of cookies to forward to the data source. |
| **Version** | Version = opentsdb version, either <=2.1 or 2.2 |
| **Resolution** | Metrics from opentsdb may have datapoints with either second or millisecond resolution. |
| **Lookup limit** | Default is 1000. |
1. Click **Connections** in the left-side menu.
1. Under Your connections, click **Data sources**.
1. Enter `OpenTSDB` in the search bar.
1. Select **OpenTSDB**.
The **Settings** tab of the data source is displayed.
1. Set the data source's basic configuration options:
| Name | Description |
| ------------------- | ---------------------------------------------------------------------------------------- |
| **Name** | The data source name. This is how you refer to the data source in panels and queries. |
| **Default** | Default data source that will be be pre-selected for new panels. |
| **URL** | The HTTP protocol, IP, and port of your OpenTSDB server (default port is usually 4242). |
| **Allowed cookies** | Listing of cookies to forward to the data source. |
| **Version** | The OpenTSDB version. |
| **Resolution** | Metrics from OpenTSDB may have data points with either second or millisecond resolution. |
| **Lookup limit** | Default is 1000. |
### Provision the data source
@@ -47,7 +56,7 @@ For more information about provisioning, and for available configuration options
apiVersion: 1
datasources:
- name: OpenTsdb
- name: OpenTSDB
type: opentsdb
access: proxy
url: http://localhost:4242
@@ -60,11 +69,13 @@ datasources:
Open a graph in edit mode by click the title. Query editor will differ if the data source has version <=2.1 or = 2.2.
In the former version, only tags can be used to query OpenTSDB. But in the latter version, filters as well as tags
can be used to query opentsdb. Fill Policy is also introduced in OpenTSDB 2.2.
can be used to query OpenTSDB. Fill Policy is also introduced in OpenTSDB 2.2.
![](/static/img/docs/v43/opentsdb_query_editor.png)
> **Note:** While using OpenTSDB 2.2 data source, make sure you use either Filters or Tags as they are mutually exclusive. If used together, might give you weird results.
{{% admonition type="note" %}}
While using OpenTSDB 2.2 data source, make sure you use either Filters or Tags as they are mutually exclusive. If used together, might give you weird results.
{{% /admonition %}}
### Auto complete suggestions

View File

@@ -214,7 +214,7 @@ The resulting table panel:
If you set Format as to _Time series_, then the query must have a column named time that returns either a SQL datetime or any numeric datatype representing Unix epoch in seconds. In addition, result sets of time series queries must be sorted by time for panels to properly visualize the result.
A time series query result is returned in a [wide data frame format]({{< relref "../../developers/plugins/data-frames#wide-format" >}}). Any column except time or of type string transforms into value fields in the data frame query result. Any string column transforms into field labels in the data frame query result.
A time series query result is returned in a [wide data frame format](https://grafana.com/developers/plugin-tools/introduction/data-frames#wide-format). Any column except time or of type string transforms into value fields in the data frame query result. Any string column transforms into field labels in the data frame query result.
> For backward compatibility, there's an exception to the above rule for queries that return three columns including a string column named metric. Instead of transforming the metric column into field labels, it becomes the field name, and then the series name is formatted as the value of the metric column. See the example with the metric column below.

View File

@@ -14,35 +14,46 @@ weight: 300
# Prometheus query editor
This topic explains querying specific to the Prometheus data source.
Grafana provides a query editor for the Prometheus data source to create queries in PromQL. For more information about PromQL, see [Querying Prometheus](http://prometheus.io/docs/querying/basics/).
For general documentation on querying data sources in Grafana, see [Query and transform data]({{< relref "../../../panels-visualizations/query-transform-data" >}}).
For options and functions common to all query editors, see [Query editors]({{< relref "../../../panels-visualizations/query-transform-data" >}}).
## Choose a query editing mode
You can switch the Prometheus query editor between two modes:
The Prometheus query editor has two modes:
- [Code mode](#code-mode), which provides a feature-rich editor for writing queries
- [Builder mode](#builder-mode), which provides a visual query designer
- [Builder mode](#builder-mode)
- [Code mode](#code-mode)
Each mode is explained in greater detail below.
{{< figure src="/static/img/docs/prometheus/editing-mode.png" max-width="500px" class="docs-image--no-shadow" caption="Query editor mode" >}}
To switch between the editor modes, select the corresponding **Builder** and **Code** tabs.
Both modes are synchronized, so you can switch between them. However, if there is an issue with the query while switching modes, a warning message will appear.
To run a query, select **Run query** in the upper right of the editor.
## Toolbar elements
Each mode is synchronized with the other modes, so you can switch between them without losing your work, although there are some limitations.
The query editor toolbar contains the following elements:
Builder mode doesn't yet support some complex queries.
When you switch from Code mode to Builder mode with such a query, the editor displays a popup that explains how you might lose parts of the query if you continue.
You can then decide whether you still want to switch to Builder mode.
- **Kick start your query** - Click to see a list of operation patterns that help you quickly get started adding multiple operations to your query. These include:
You can also use the [Explain feature]({{< relref "#use-explain-mode-to-understand-queries" >}}) to help understand how a query works, and augment queries by using [template variables]({{< relref "./template-variables/" >}}).
- Rate query starters
- Histogram query starters
- Binary query starters
For options and functions common to all query editors, refer to [Query and transform data]({{< relref "../../../panels-visualizations/query-transform-data" >}}).
Click the arrow next to each to see available options to add to your query.
- **Explain** - Toggle to display a step-by-step explanation of all query components and operations.
{{< figure src="/static/img/docs/prometheus/explain-results.png" max-width="500px" class="docs-image--no-shadow" caption="Explain results" >}}
- **Builder/Code** - Click the corresponding **Builder** or **Code** tab on the toolbar to select a editor mode.
## Configure common options
You can configure Prometheus-specific options in the query editor by setting several options regardless of its mode.
You can configure Prometheus-specific options in the query editor by setting several options regardless of mode.
{{< figure src="/static/img/docs/prometheus/options.png" max-width="500px" class="docs-image--no-shadow" caption="Options" >}}
@@ -50,11 +61,9 @@ You can configure Prometheus-specific options in the query editor by setting sev
The **Legend** setting defines the time series's name. You can use a predefined or custom format.
| Option | Description |
| ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Auto** | Shows the value of a single label for each series with only one label, or displays all labels if a series has multiple labels. |
| **Verbose** | Displays all label names. |
| **Custom** | Uses templating to select which labels will be included.<br/>For example, `{{hostname}}` is replaced by the label value for the label `hostname`.<br/>Clear the input and click outside of it to select another mode. |
- **Auto** - Displays unique labels. Also displays all overlapping labels if a series has multiple labels.
- **Verbose** - Displays all label names.
- **Custom** - Uses templating to select which labels will be included. For example, `{{hostname}}` is replaced by the label value for the label `hostname`. Clear the input and click outside of it to select another mode.
### Min step
@@ -64,97 +73,61 @@ This setting supports the `$__interval` and `$__rate_interval` macros.
### Format
You can switch between **Table**, **Time series**, and **Heatmap** options by configuring the query's **Format**.
Switch between the following format options:
| Option | Description |
| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Table** | This works only in a [Table panel]({{< relref "../../../panels-visualizations/visualizations/table" >}}). |
| **Time series** | Uses the default time series format. |
| **Heatmap** | Displays metrics of the Histogram type on a [Heatmap panel]({{< relref "../../../panels-visualizations/visualizations/heatmap" >}}) by converting cumulative histograms to regular ones and sorting the series by the bucket bound. |
- **Time series** - The default time series format. See [Time series kind formats](https://grafana.github.io/dataplane/timeseries/) for information on time series data frames and how time and value fields are structured.
- **Table** - This works only in a [Table panel]({{< relref "../../../panels-visualizations/visualizations/table" >}}).
- **Heatmap** - Displays metrics of the Histogram type on a [Heatmap panel]({{< relref "../../../panels-visualizations/visualizations/heatmap" >}}) by converting cumulative histograms to regular ones and sorting the series by the bucket bound.
### Type
The **Type** setting selects the query type.
The **Type** setting sets the query type. These include:
- A **Range** query returns a Range vector, comprised of a set of time series containing a range of data points over time for each time series.
- An **Instant** query returns only the latest value that Prometheus has scraped for the requested time series. Instant queries can return results much faster than normal range queries and are well suited to look up label sets.
- **Both** - The default option. Returns results for both a **Range** query and an **Instant** query.
- **Range** - Returns a range vector consisting of a set of time series data containing a range of data points over time for each time series. You can choose lines, bars, points, stacked lines or stacked bars
- **Instant** - Returns one data point per query and only the most recent point in the time range provided. The results can be shown in table format or as raw data. To depict instant query results in the time series panel, first add a field override, next add a property to the override named `Transform`, and finally select `Constant` from the **Transform** dropdown.
Instant query results are comprised of only one data point per series and can be shown in the time series panel by adding a field override, adding a property to the override named `Transform`, and selecting `Constant` from the **Transform** dropdown.
For more information, refer to the [Time Series Transform option documentation]({{< relref "../../../panels-visualizations/visualizations/time-series#transform" >}}).
For more information, refer to the [Time Series Transform option documentation]({{< relref "../../../panels-visualizations/visualizations/time-series#transform" >}}).
{{% admonition type="note" %}}
Grafana modifies the request dates for queries to align them with the dynamically calculated step.
This ensures a consistent display of metrics data, but it can result in a small gap of data at the right edge of a graph.
{{% /admonition %}}
- An **Exemplars** query runs with the regular query and shows exemplars in the graph.
### Exemplars
> **Note:** Grafana modifies the request dates for queries to align them with the dynamically calculated step.
> This ensures a consistent display of metrics data, but it can result in a small gap of data at the right edge of a graph.
Toggle **Exemplars** to run a query that includes exemplars in the graph. Exemplars are unique to Prometheus. For more information see [Introduction to exemplars](https://grafana.com/docs/grafana/latest/fundamentals/exemplars/).
## Code mode
{{% admonition type="note" %}}
There is no option to add exemplars with an **Instant** query type.
{{% /admonition %}}
{{< figure src="/static/img/docs/prometheus/code-mode.png" max-width="500px" class="docs-image--no-shadow" caption="Code mode" >}}
### Inspector
In **Code mode**, you can write complex queries using a text editor with autocompletion features and syntax highlighting.
It also contains a [Metrics browser]({{< relref "#metrics-browser" >}}) to further help you write queries.
Click **Inspector** to get detailed statistics regarding your query. Inspector functions as a kind of debugging tool that "inspects" your query. It provides query statistics under **Stats**, request response time under **Query**, data frame details under **{} JSON**, and the shape of your data under **Data**.
For more information about Prometheus's query language (PromQL), see [Querying Prometheus](http://prometheus.io/docs/querying/basics/).
### Use autocompletion
Code mode's autocompletion feature works automatically while typing.
The query editor can autocomplete static functions, aggregations, keywords, and also dynamic items like metrics and labels.
The autocompletion dropdown includes documentation for the suggested items where available.
To run a query in [Explore]({{< relref "../../../explore/" >}}), use the keyboard shortcut <key>Shift</key> + <key>Enter</key>.
### Metrics browser
The metrics browser locates metrics and selects relevant labels to help you build basic queries.
When you open the browser, it displays all available metrics and labels.
If supported by your Prometheus instance, each metric also displays its HELP and TYPE as a tooltip.
{{< figure src="/static/img/docs/prometheus/metric-browser.png" max-width="500px" class="docs-image--no-shadow" caption="Metrics browser" >}}
When you select a metric, the browser narrows down the available labels to show only the ones applicable to the metric.
You can then select one or more labels for which the available label values are shown in lists in the bottom section.
Select one or more values for each label to tighten your query scope.
> **Note:** If you do not remember a metric name to start with, you can also select a few labels to narrow down the list, then find relevant label values.
All lists in the metrics browser have a search field above them to quickly filter for metrics or labels that match a certain string.
The values section has only one search field, and its filtering applies to all labels to help you find values across labels once selected.
For example, among your labels `app`, `job`, `job_name` only one might with the value you are looking for.
Once you are satisfied with your query, click "Use query" to run the query. The button "Use as rate query" adds a `rate(...)[$__interval]` around your query to help write queries for counter metrics.
The "Validate selector" button will check with Prometheus how many time series are available for that selector.
{{< figure src="/static/img/docs/prometheus/insepctor-9-5.png" max-width="500px" class="docs-image--no-shadow" caption="Inspector" >}}
## Builder mode
In **Builder mode**, you can build queries using a visual interface.
**Builder mode** helps you build queries using a visual interface. This option is best for users who have limited or no previous experience working with Prometheus and PromQL.
This video demonstrates how to use the visual Prometheus query builder available since Grafana v9.0:
This video demonstrates how to use the visual Prometheus query builder available in Grafana v9.0:
{{< vimeo 720004179 >}}
</br>
### Toolbar
In addition to the **Run query** button and mode switcher, Builder mode includes additional elements:
| Name | Description |
| ------------------------- | ----------------------------------------------------------------------------------------- |
| **Kick start your query** | A list of operation patterns that help you quickly add multiple operations to your query. |
| **Explain** | Displays a step-by-step explanation of all query parts and its operations. |
### Metric and labels
### Metrics
{{< figure src="/static/img/docs/prometheus/metrics-and-labels.png" max-width="500px" class="docs-image--no-shadow" caption="Metric and label filters" >}}
Select a specific metric name from the dropdown list.
When you are ready to create a query, you can choose the specific metric name from the dropdown list under **Metric**.
The data source requests the list of available metrics from the Prometheus server based on the selected time rage.
You can also enter text into the selector when the dropdown is open to search and filter the list.
### Label filters
Select desired labels and their values from the dropdown list.
When a metric is selected, the data source requests available labels and their values from the server.
Use the `+` button to add a label, and the `x` button to remove a label.
@@ -163,53 +136,71 @@ Use the `+` button to add a label, and the `x` button to remove a label.
{{< figure src="/static/img/docs/prometheus/operations.png" max-width="500px" class="docs-image--no-shadow" caption="Operations" >}}
Select the `+ Operations` button to add operations to your query.
The query editor groups operations into related sections, and you can type while the operations dropdown is open to search and filter the list.
Select the **+ Operations** button to add operations to your query.
The query editor displays a query's operations as boxes in the operations section.
Each operation's header displays its name, and additional action buttons appear when you hover your cursor over the header:
The query editor groups operations into the following sections:
| Button | Action |
| ------ | ----------------------------------------------------------------- |
| `v` | Replaces the operation with different operation of the same type. |
| `info` | Opens the operation's description tooltip. |
| `x` | Removes the operation. |
- Aggregations - for additional information see [Aggregation operators](https://prometheus.io/docs/prometheus/latest/querying/operators/#aggregation-operators).
- Range functions - for additional information see [Functions](https://prometheus.io/docs/prometheus/latest/querying/functions/#functions).
- Functions - for additional information see [Functions](https://prometheus.io/docs/prometheus/latest/querying/functions/#functions).
- Binary operations - for additional information see [Binary operators](https://prometheus.io/docs/prometheus/latest/querying/operators/#binary-operators).
- Trigonometric - for additional information see [Trigonometric functions](https://prometheus.io/docs/prometheus/latest/querying/functions/#trigonometric-functions).
- Time functions - for additional information see [Functions](https://prometheus.io/docs/prometheus/latest/querying/functions/#functions).
Some operations have additional parameters under the operation header.
For details about each operation, use the `info` button to view the operation's description, or refer to the Prometheus documentation on [query functions](https://prometheus.io/docs/prometheus/latest/querying/functions/).
All operations have function parameters under the operation header. Click the `operator` to see a full list of supported functions. Some operations allow you to apply specific labels to functions.
{{< figure src="/static/img/docs/prometheus/use-function-by-label-9-5.png" max-width="500px" class="docs-image--no-shadow" caption="Functions and labels" >}}
Some operations make sense only when used in a specific order.
If adding an operation would result in nonsensical query, the query editor adds the operation to the correct place.
To re-order operations manually, drag the operation box by its name and drop it into the desired place.
#### Hints
{{< figure src="/static/img/docs/prometheus/hint-example.png" max-width="500px" class="docs-image--no-shadow" caption="Hint" >}}
The query editor can detect which operations are most appropriate for some selected metrics.
If it does, it displays a hint next to the `+ Operations` button.
If it does, it displays a hint next to the **+ Operations** button.
To add the operation to your query, click the `hint`.
To add the operation to your query, click the **Hint**.
## Use Explain mode to understand queries
Once you are satisfied with your query, click **Run query**.
{{< figure src="/static/img/docs/prometheus/explain-results.png" max-width="500px" class="docs-image--no-shadow" caption="Explain results" >}}
## Code mode
Explain mode helps you understand a query by displaying a step-by-step explanation of all query components and operations.
**Code mode** is for the experienced Prometheus user with prior expertise in PromQL, Prometheus' query language. The Code mode editor allows you to create queries just as you would in Prometheus. For more information about PromQL see [Querying Prometheus](http://prometheus.io/docs/querying/basics/).
### Additional options
{{< figure src="/static/img/docs/prometheus/code-mode.png" max-width="500px" class="docs-image--no-shadow" caption="Code mode" >}}
In addition to these Builder mode-specific options, the query editor also displays the options it shares in common with Code mode.
For details, refer to the [common options]({{< relref "#configure-common-options" >}}).
The user interface (UI) also lets you select metrics, labels, filters and operations.
## Apply annotations
You can write complex queries using the text editor with autocompletion features and syntax highlighting.
It also contains a [Metrics browser]({{< relref "#metrics-browser" >}}) to further help you write queries.
[Annotations]({{< relref "../../../dashboards/build-dashboards/annotate-visualizations" >}}) overlay rich event information on top of graphs.
You can add annotation queries in the Dashboard menu's Annotations view.
### Use autocomplete
Prometheus supports two ways to query annotations.
Code mode's autocomplete feature works automatically while typing. The query editor can autocomplete static functions, aggregations, keywords, and also dynamic items like metrics and labels.
The autocompletion dropdown includes documentation for the suggested items where available.
- A regular metric query
- A Prometheus query for pending and firing alerts (for details see [Inspecting alerts during runtime](https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/#inspecting-alerts-during-runtime))
### Metrics browser
The step option is useful to limit the number of events returned from your query.
The metrics browser locates metrics and selects relevant labels to help you build basic queries.
When you click **Metrics browser**, it displays all available metrics and labels.
If supported by your Prometheus instance, each metric also displays its `HELP` and `TYPE` as a tooltip.
{{< figure src="/static/img/docs/prometheus/metric-browser.png" max-width="500px" class="docs-image--no-shadow" caption="Metrics browser" >}}
When you select a metric under Step 1, the browser narrows down the available labels to show only the ones applicable to the metric.
You can then select one or more labels shown in Step 2.
Select one or more values in Step 3 for each label to tighten your query scope.
In Step 4, you can select **Use query** to run the query, **Use as rate query** to add the rate operation to your query (`$__rate_interval`), **Validate selector** to verify the selector is valid and show the number of series found, or **Clear** to clear your selections and start over.
{{% admonition type="note" %}}
If you do not remember a metric name, you can also select a few labels to narrow down the list, then find relevant label values.
{{% /admonition %}}
All lists in the metrics browser have a search field above them to quickly filter for metrics or labels that match a certain string.
The values section has only one search field, and its filtering applies to all labels to help you find values across labels once selected.
For example, among your labels `app`, `job`, `job_name` only one might have the value you are looking for.
Once you are satisfied with your query, click **Run query**.

View File

@@ -39,7 +39,7 @@ The data source doesn't provide any settings beyond the most basic options commo
## Create mock data
{{< figure src="/static/img/docs/v41/test_data_add.png" class="docs-image--no-shadow" caption="Adding test data" >}}
{{< figure src="/media/docs/grafana/data-sources/screenshot-testdata-add-10.0.png" class="docs-image--no-shadow" caption="Adding test data" >}}
Once you've added the TestData data source, your Grafana instance's users can use it as a data source in any metric panel.
@@ -49,7 +49,7 @@ Instead of providing a query editor, the TestData data source helps you select a
You can assign an **Alias** to each scenario, and many have their own options that appear when selected.
{{< figure src="/static/img/docs/v41/test_data_csv_example.png" class="docs-image--no-shadow" caption="Using CSV Metric Values" >}}
{{< figure src="/media/docs/grafana/data-sources/screenshot-testdata-csv-example-10.0.png" class="docs-image--no-shadow" caption="Using CSV Metric Values" >}}
**Available scenarios:**

View File

@@ -56,6 +56,6 @@ Grafana Enterprise includes all of the Grafana OSS APIs as well as those that fo
- [Role-based access control API]({{< relref "access_control/" >}})
- [Data source permissions API]({{< relref "datasource_permissions/" >}})
- [External group sync API]({{< relref "external_group_sync/" >}})
- [Team sync API]({{< relref "team_sync/" >}})
- [License API]({{< relref "licensing/" >}})
- [Reporting API]({{< relref "reporting/" >}})

View File

@@ -57,10 +57,8 @@ Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
- **dashboard.id** id = null to create a new dashboard.
- **dashboard.uid** Optional unique identifier when creating a dashboard. uid = null will generate a new uid.
- **dashboard.refresh** - Set the dashboard refresh interval. If this is lower than [the minimum refresh interval]({{< relref "/docs/grafana/latest/setup-grafana/configure-grafana#min_refresh_interval" >}}), then Grafana will ignore it and will enforce the minimum refresh interval.
- **folderUid** The UID of the folder to save the dashboard in. Overrides the `folderId`.
- **folderId** The id of the folder to save the dashboard in.
- **folderUid** The UID of the folder to save the dashboard in. Overrides the `folderId`.
- **refresh** - Set the dashboard refresh interval. If this is lower than [the minimum refresh interval]({{< relref "/docs/grafana/latest/setup-grafana/configure-grafana#min_refresh_interval" >}}), then Grafana will ignore it and will enforce the minimum refresh interval.
- **overwrite** Set to true if you want to overwrite existing dashboard with newer version, same dashboard title in folder or same dashboard uid.
- **message** - Set a commit message for the version history.
@@ -69,169 +67,36 @@ Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
```http
POST /api/dashboards/db HTTP/1.1
Accept: application/json
Content-Type: application/json; charset=UTF-8
Content-Type: application/json
Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
```
**Example Response**:
```http
```http
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 78
```
Content-Type: application/json; charset=UTF-8
Content-Length: 78
- **200** Created
- **400** Errors (invalid json, missing or invalid fields, etc)
```
Status Codes:
- **200** Created
- **400** Errors (invalid json, missing or invalid fields, etc)
- **412** Precondition failed
The **412** status code is used for explaining that you cannot create the dashboard and why.
There can be different reasons for this:
- The dashboard has been changed by someone else, `status=version-mismatch`
- A dashboard with the same name in the folder already exists, `status=name-exists`
- A dashboard with the same uid already exists, `status=name-exists`
- The dashboard belongs to plugin `<plugin title>`, `status=plugin-dashboard`
The response body will have the following properties:
```http
HTTP/1.1 412 Precondition Failed
Content-Type: application/json; charset=UTF-8
Content-Length: 97
```
In case of title already exists the `status` property will be `name-exists`.
## Get dashboard by uid
`GET /api/dashboards/uid/:uid`
Will return the dashboard given the dashboard unique identifier (uid). Information about the unique identifier of a folder containing the requested dashboard might be found in the metadata.
**Required permissions**
See note in the [introduction]({{< ref "#dashboard-api" >}}) for an explanation.
| Action | Scope |
| ----------------- | -------------- |
| `dashboards:read` | `dashboards:*` |
**Example Request**:
```http
GET /api/dashboards/uid/cIBgcSjkk HTTP/1.1
Accept: application/json
Content-Type: application/json
Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
```
**Example Response**:
```http
HTTP/1.1 200
Content-Type: application/json
```
Status Codes:
- **200** Found
- **401** Unauthorized
- **403** Access denied
- **404** Not found
## Delete dashboard by uid
`DELETE /api/dashboards/uid/:uid`
Will delete the dashboard given the specified unique identifier (uid).
**Required permissions**
See note in the [introduction]({{< ref "#dashboard-api" >}}) for an explanation.
| Action | Scope |
| ------------------- | ----------------------------- |
| `dashboards:delete` | `dashboards:*`<br>`folders:*` |
**Example Request**:
```http
DELETE /api/dashboards/uid/cIBgcSjkk HTTP/1.1
Accept: application/json
Content-Type: application/json
Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
```
**Example Response**:
```http
HTTP/1.1 200
Content-Type: application/json
```
Status Codes:
- **200** Deleted
- **401** Unauthorized
- **403** Access denied
- **404** Not found
## Gets the home dashboard
`GET /api/dashboards/home`
Will return the home dashboard.
**Example Request**:
```http
GET /api/dashboards/home HTTP/1.1
Accept: application/json
Content-Type: application/json
Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
```
**Example Response**:
```http
HTTP/1.1 200
Content-Type: application/json
```
## Tags for Dashboard
`GET /api/dashboards/tags`
Get all tags of dashboards
**Example Request**:
```http
GET /api/dashboards/tags HTTP/1.1
Accept: application/json
Content-Type: application/json
Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
```
**Example Response**:
```http
HTTP/1.1 200
Content-Type: application/json
```
- **401** Unauthorized
- **403** Access denied
- **412** Precondition failed
The **412** status code is used for explaining that you cannot create the dashboard and why.
There can be different reasons for this:
- The dashboard has been changed by someone else, `status=version-mismatch`
- A dashboard with the same name in the folder already exists, `status=name-exists`
- A dashboard with the same uid already exists, `status=name-exists`
- The dashboard belongs to plugin `<plugin title>`, `status=plugin-dashboard`
The response body will have the following properties:
```http
@@ -243,12 +108,12 @@ Content-Type: application/json; charset=UTF-8
In case of title already exists the `status` property will be `name-exists`.
"id": 1,
"uid": "cIBgcSjkk",
"url": "/d/cIBgcSjkk/production-overview",
"status": "success",
"version": 1,
"slug": "production-overview" //deprecated in Grafana v5.0
## Get dashboard by uid
`GET /api/dashboards/uid/:uid`
Will return the dashboard given the dashboard unique identifier (uid). Information about the unique identifier of a folder containing the requested dashboard might be found in the metadata.
**Required permissions**
See note in the [introduction]({{< ref "#dashboard-api" >}}) for an explanation.

View File

@@ -30,14 +30,14 @@ Returns a list of all library elements the authenticated user has permission to
Query parameters:
- **searchString** Part of the name or description searched for.
- **kind** Kind of element to search for. Use `1` for library panels or `2` for library variables.
- **sortDirection** Sort order of elements. Use `alpha-asc` for ascending and `alpha-desc` for descending sort order.
- **typeFilter** A comma separated list of types to filter the elements by.
- **excludeUid** Element UID to exclude from search results.
- **folderFilter** A comma separated list of folder ID(s) to filter the elements by.
- **perPage** The number of results per page; default is 100.
- **page** The page for a set of records, given that only `perPage` records are returned at a time. Numbering starts at `1`.
- `searchString`: Part of the name or description searched for.
- `kind`: Kind of element to search for. Use `1` for library panels or `2` for library variables.
- `sortDirection`: Sort order of elements. Use `alpha-asc` for ascending and `alpha-desc` for descending sort order.
- `typeFilter`: A comma separated list of types to filter the elements by.
- `excludeUid`: Element UID to exclude from search results.
- `folderFilter`: A comma separated list of folder IDs to filter the elements by.
- `perPage`: The number of results per page; default is 100.
- `page`: The page for a set of records, given that only `perPage` records are returned at a time. Numbering starts at `1`.
**Example Request**:
@@ -98,8 +98,8 @@ Content-Type: application/json
**Example Request**:
```http
GET /api/library-elements/name/API docs Example HTTP/1.1
```http
GET /api/library-elements/name/API docs Example HTTP/1.1
Accept: application/json
Content-Type: application/json
Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
@@ -157,9 +157,9 @@ Content-Type: application/json
JSON Body schema:
- `folderId`: ID of the folder where the library element is stored. It is deprecated since Grafana v9
- **folderUid** Optional, the UID of the folder where the library element is stored, empty string when it is General folder
- **name** Optional, the name of the library element.
- **model** The JSON model for the library element.
- `folderUid`: Optional, the UID of the folder where the library element is stored, empty string when it is General folder
- `name`: Optional, the name of the library element.
- `model`: The JSON model for the library element.
- `kind`: Kind of element to create, Use `1` for library panels or `2` for library variables.
- `uid`: Optional, the [unique identifier](/http_api/library_element/#identifier-id-vs-unique-identifier-uid).
@@ -219,9 +219,9 @@ Content-Type: application/json
```http
HTTP/1.1 200
Content-Type: application/json
```
```
Status Codes:
- `200`: Updated
@@ -265,9 +265,9 @@ Content-Type: application/json
- `403`: Access denied
- `404`: Library element not found
- **200** Found
- **401** Unauthorized
- **404** Library element not found
- `200`: Found
- `401`: Unauthorized
- `404`: Library element not found
## Create library element
@@ -277,12 +277,12 @@ Creates a new library element.
JSON Body schema:
- **folderId** ID of the folder where the library element is stored. It is deprecated since Grafana v9
- **folderUid** Optional, the UID of the folder where the library element is stored, empty string when it is General folder
- **name** Optional, the name of the library element.
- **model** The JSON model for the library element.
- **kind** Kind of element to create, Use `1` for library panels or `2` for library variables.
- **uid** Optional, the [unique identifier](/http_api/library_element/#identifier-id-vs-unique-identifier-uid).
- `folderId`: ID of the folder where the library element is stored. It is deprecated since Grafana v9
- `folderUid`: Optional, the UID of the folder where the library element is stored, empty string when it is General folder
- `name`: Optional, the name of the library element.
- `model`: The JSON model for the library element.
- `kind`: Kind of element to create, Use `1` for library panels or `2` for library variables.
- `uid`: Optional, the [unique identifier](/http_api/library_element/#identifier-id-vs-unique-identifier-uid).
**Example Request**:
@@ -343,10 +343,10 @@ Content-Type: application/json
Status Codes:
- **200** Created
- **400** Errors (for example, name or UID already exists, invalid JSON, missing or invalid fields, and so on).
- **401** Unauthorized
- **403** Access denied
- `200`: Created
- `400`: Errors (for example, name or UID already exists, invalid JSON, missing or invalid fields, and so on).
- `401`: Unauthorized
- `403`: Access denied
## Update library element
@@ -356,13 +356,13 @@ Updates an existing library element identified by uid.
JSON Body schema:
- **folderId** ID of the folder where the library element is stored. It is deprecated since Grafana v9
- **folderUid** UID of the folder where the library element is stored, empty string when it is General folder.
- **name** Name of the library element.
- **model** The JSON model for the library element.
- **kind** Kind of element to create. Use `1` for library panels or `2` for library variables.
- **version** Version of the library element you are updating.
- **uid** Optional, the [unique identifier](/http_api/library_element/#identifier-id-vs-unique-identifier-uid).
- `folderId`: ID of the folder where the library element is stored. It is deprecated since Grafana v9
- `folderUid`: UID of the folder where the library element is stored, empty string when it is General folder.
- `name`: Name of the library element.
- `model`: The JSON model for the library element.
- `kind`: Kind of element to create. Use `1` for library panels or `2` for library variables.
- `version`: Version of the library element you are updating.
- `uid`: Optional, the [unique identifier](/http_api/library_element/#identifier-id-vs-unique-identifier-uid).
**Example Request**:
@@ -424,12 +424,12 @@ Content-Type: application/json
Status Codes:
- **200** Updated
- **400** Errors (for example, name or UID already exists, invalid JSON, missing or invalid fields, and so on).
- **401** Unauthorized
- **403** Access denied
- **404** Library element not found
- **412** Version mismatch
- `200`: Updated
- `400`: Errors (for example, name or UID already exists, invalid JSON, missing or invalid fields, and so on).
- `401`: Unauthorized
- `403`: Access denied
- `404`: Library element not found
- `412`: Version mismatch
## Delete library element
@@ -463,8 +463,8 @@ Content-Type: application/json
Status Codes:
- **200** Deleted
- **401** Unauthorized
- **400** Bad request
- **403** Access denied
- **404** Library element not found
- `200`: Deleted
- `401`: Unauthorized
- `400`: Bad request
- `403`: Access denied
- `404`: Library element not found

View File

@@ -217,8 +217,168 @@ Content-Type: application/json
Authorization: Basic YWRtaW46YWRtaW4=
```
**Example Response**:
```http
HTTP/1.1 200
Content-Type: application/json
```
## Get API key to service account migration status
`GET /api/serviceaccounts/migrationstatus`
**Required permissions**
See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation.
| Action | Scope |
| -------------------- | ------------------ |
| serviceaccounts:read | serviceaccounts:\* |
**Example Request**:
```http
POST /api/serviceaccounts/migrationstatus HTTP/1.1
Accept: application/json
Content-Type: application/json
Authorization: Basic YWRtaW46YWRtaW4=
```
**Example Response**:
```http
HTTP/1.1 200
Content-Type: application/json
```
## Hide the API keys tab
`GET /api/serviceaccounts/hideApiKeys`
**Required permissions**
See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation.
| Action | Scope |
| --------------------- | ------------------ |
| serviceaccounts:write | serviceaccounts:\* |
**Example Request**:
```http
POST /api/serviceaccounts/hideApiKeys HTTP/1.1
Accept: application/json
Content-Type: application/json
Authorization: Basic YWRtaW46YWRtaW4=
```
**Example Response**:
```http
HTTP/1.1 200
Content-Type: application/json
```
## Get service account tokens
`GET /api/serviceaccounts/:id/tokens`
**Required permissions**
See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation.
| Action | Scope |
| -------------------- | --------------------- |
| serviceaccounts:read | serviceaccounts:id:\* |
**Example Request**:
```http
GET /api/serviceaccounts/2/tokens HTTP/1.1
Accept: application/json
Content-Type: application/json
Authorization: Basic YWRtaW46YWRtaW4=
```
**Example Response**:
```http
HTTP/1.1 200
Content-Type: application/json
```
## Create service account tokens
`POST /api/serviceaccounts/:id/tokens`
**Required permissions**
See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation.
| Action | Scope |
| --------------------- | --------------------- |
| serviceaccounts:write | serviceaccounts:id:\* |
**Example Request**:
```http
POST /api/serviceaccounts/2/tokens HTTP/1.1
Accept: application/json
Content-Type: application/json
Authorization: Basic YWRtaW46YWRtaW4=
```
**Example Response**:
```http
HTTP/1.1 200
Content-Type: application/json
```
## Delete service account tokens
`DELETE /api/serviceaccounts/:id/tokens/:tokenId`
**Required permissions**
See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation.
| Action | Scope |
| --------------------- | --------------------- |
| serviceaccounts:write | serviceaccounts:id:\* |
**Example Request**:
```http
DELETE /api/serviceaccounts/2/tokens/1 HTTP/1.1
Accept: application/json
Content-Type: application/json
Authorization: Basic YWRtaW46YWRtaW4=
```
**Example Response**:
```http
HTTP/1.1 200
Content-Type: application/json
```
## Revert service account token to API key
`DELETE /api/serviceaccounts/:serviceAccountId/revert/:keyId`
This operation will delete the service account and create a legacy API Key for the given `keyId`.
**Required permissions**
See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation.
| Action | Scope |

View File

@@ -1,8 +1,9 @@
---
aliases:
- ../../http_api/external_group_sync/
canonical: /docs/grafana/latest/developers/http_api/external_group_sync/
description: Grafana External Group Sync HTTP API
- ./external_group_sync/
canonical: /docs/grafana/latest/developers/http_api/team_sync/
description: Grafana Team Sync HTTP API
keywords:
- grafana
- http
@@ -13,12 +14,12 @@ keywords:
- group
- member
- enterprise
title: External Group Sync HTTP API
title: Team Sync HTTP API
---
# External Group Synchronization API
# Team Sync API
> External Group Synchronization is only available in Grafana Enterprise. Read more about [Grafana Enterprise]({{< relref "/docs/grafana/latest/introduction/grafana-enterprise" >}}).
> Team Sync is only available in Grafana Enterprise. Read more about [Grafana Enterprise]({{< relref "/docs/grafana/latest/introduction/grafana-enterprise" >}}).
> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes" >}}) for more information.

View File

@@ -1,52 +0,0 @@
---
aliases:
- ../plugins/developing/
description: Resources for creating Grafana plugins
title: Plugin developer's guide
weight: 200
---
# Grafana plugin developer's guide
You can extend Grafana's built-in capabilities with plugins. Plugins enable Grafana to accomplish specialized tasks, custom-tailored to your requirements. By making a plugin for your organization, you can connect Grafana to other data sources, ticketing tools, and CI/CD tooling.
You can create plugins for private use or contribute them to the open source community by publishing to the [Grafana plugin catalog](https://grafana.com/grafana/plugins/). This catalog has hundreds of other community and commercial plugins.
If you are a Grafana plugin developer or want to become one, this plugin developer's guide contains the tutorials and reference materials to help you get started.
## Plugin basics
You can create several types of plugins, including:
- **Panel plugins** - Visualize data and navigate between dashboards.
- **Data source plugins** - Link to new databases or other sources of data.
- **App plugins** - Create rich applications for custom out-of-the-box experiences.
> **Note:** To learn more about the types of plugins you can build, refer to the [Plugin management]({{< relref "../../administration/plugin-management" >}}) documentation.
## Contents of this developer's guide
The following topics are covered in this guide:
- **[Get started with plugins]({{< relref "./get-started-with-plugins" >}})** - Start developing Grafana plugins with the [Create-plugin](https://www.npmjs.com/package/@grafana/create-plugin) tool.
- **[Introduction to plugin development]({{< relref "./introduction-to-plugin-development" >}})** - Learn the fundamentals of Grafana plugin development: frontend and backend development processes, data frames, error handling, and more.
- **[Create a Grafana plugin]({{< relref "./create-a-grafana-plugin" >}})** - If you're familiar with plugin creation, use the tutorials for creating panel plugins, data source plugins, and more to deepen your knowledge.
- **[Migrate a plugin]({{< relref "./migration-guide" >}})** - Learn how to upgrade from a previous version of a Grafana plugin, rewrite an old Angular plugin in React, or update to a newer version.
- **[Publish a Grafana plugin]({{< relref "./publish-a-plugin" >}})** - Learn about publishing a plugin to the Grafana plugin catalog, including publishing criteria, packaging, and deployment.
- **[Reference]({{< relref "metadata.md" >}})** - Description of the `plugin.json` schema and plugin metadata.
## Go further
Learn more about additional tools and see plugin type examples.
### User interface creation
Explore the many UI components in our [Grafana UI library](/ui).
### Plugin examples
Grafana Labs provides a number of best practice example plugins for different use cases to help you quickly get started. Browse our [plugin examples](https://github.com/grafana/grafana-plugin-examples).
### SDK
Learn more about [Grafana Plugin SDK for Go]({{< relref "./backend/grafana-plugin-sdk-for-go" >}}).

View File

@@ -1,166 +0,0 @@
---
title: Add anonymous usage reporting
---
# Add anonymous usage reporting
Add anonymous usage tracking to your plugin to send [reporting events]({{< relref "../../setup-grafana/configure-grafana/#reporting_enabled" >}}) that describe how your plugin is being used to a tracking system configured by your Grafana server administrator.
## Event reporting
In this section, we show an example of tracking usage data from a query editor and receiving a report back from the analytics service.
### Sample query editor
Let's say you have a `QueryEditor` that looks similar to the example below. It has a `CodeEditor` field where you can write your query and a query type selector so you can select the kind of query result that you expect to return:
```ts
import React, { ReactElement } from 'react';
import { InlineFieldRow, InlineField, Select, CodeEditor } from '@grafana/ui';
import type { EditorProps } from './types';
export function QueryEditor(props: EditorProps): ReactElement {
const { datasource, query, onChange, onRunQuery } = props;
const queryType = { value: query.value ?? 'timeseries' };
const queryTypes = [
{
label: 'Timeseries',
value: 'timeseries',
},
{
label: 'Table',
value: 'table',
},
];
const onChangeQueryType = (type: string) => {
onChange({
...query,
queryType: type,
});
runQuery();
};
const onChangeRawQuery = (rawQuery: string) => {
onChange({
...query,
rawQuery: type,
});
runQuery();
};
return (
<>
<div>
<CodeEditor
height="200px"
showLineNumbers={true}
language="sql"
onBlur={onChangeRawQuery}
value={query.rawQuery}
/>
</div>
<InlineFieldRow>
<InlineField label="Query type" grow>
<Select options={queryTypes} onChange={onChangeQueryType} value={queryType} />
</InlineField>
</InlineFieldRow>
</>
);
}
```
### Track usage with `usePluginInteractionReporter`
Let's say that you want to track how the usage looks between time series and table queries.
What you want to do is to add the `usePluginInteractionReporter` to fetch a report function that takes two arguments:
- Required: An event name that begins with `grafana_plugin_`. It is used to identify the interaction being made.
- Optional: Attached contextual data. In our example, that is the query type.
```ts
import React, { ReactElement } from 'react';
import { InlineFieldRow, InlineField, Select, CodeEditor } from '@grafana/ui';
import { usePluginInteractionReporter } from '@grafana/runtime';
import type { EditorProps } from './types';
export function QueryEditor(props: EditorProps): ReactElement {
const { datasource, query, onChange, onRunQuery } = props;
const report = usePluginInteractionReporter();
const queryType = { value: query.value ?? 'timeseries' };
const queryTypes = [
{
label: 'Timeseries',
value: 'timeseries',
},
{
label: 'Table',
value: 'table',
},
];
const onChangeQueryType = (type: string) => {
onChange({
...query,
queryType: type,
});
runQuery();
};
const onChangeRawQuery = (rawQuery: string) => {
onChange({
...query,
rawQuery: type,
});
report('grafana_plugin_executed_query', {
query_type: queryType.value,
});
runQuery();
};
return (
<>
<div>
<CodeEditor
height="200px"
showLineNumbers={true}
language="sql"
onBlur={onChangeRawQuery}
value={query.rawQuery}
/>
</div>
<InlineFieldRow>
<InlineField label="Query type" grow>
<Select options={queryTypes} onChange={onChangeQueryType} value={queryType} />
</InlineField>
</InlineFieldRow>
</>
);
}
```
### Data returned from the analytics service
When you use `usePluginInteractionReporter`, the report function that is handed back to you automatically attaches contextual data about the plugin you are tracking to the events.
In our example, the following information is sent to the analytics service configured by the Grafana server administrator:
```ts
{
type: 'interaction',
payload: {
interactionName: 'grafana_plugin_executed_query',
grafana_version: '9.2.1',
plugin_type: 'datasource',
plugin_version: '1.0.0',
plugin_id: 'grafana-example-datasource',
plugin_name: 'Example',
datasource_uid: 'qeSI8VV7z', // will only be added for datasources
query_type: 'timeseries'
}
}
```

View File

@@ -1,459 +0,0 @@
---
aliases:
- ../../plugins/developing/auth-for-datasources/
- /docs/grafana/next/developers/plugins/authentication/
title: Add authentication for data source plugins
---
# Add authentication for data source plugins
Grafana plugins can perform authenticated requests against a third-party API by using the _data source proxy_ or through a custom a _backend plugin_.
## Choose an authentication method
Configure your data source plugin to authenticate against a third-party API in one of either of two ways:
- Use the [_data source proxy_](#authenticate-using-the-data-source-proxy) method, or
- Build a [_backend plugin_](#authenticate-using-a-backend-plugin).
| Case | Use |
| ----------------------------------------------------------------------------------------------- | ------------------------------- |
| Do you need to authenticate your plugin using Basic Auth or API keys? | Use the data source proxy. |
| Does your API support OAuth 2.0 using client credentials? | Use the data source proxy. |
| Does your API use a custom authentication method that isn't supported by the data source proxy? | Use a backend plugin. |
| Does your API communicate over a protocol other than HTTP? | Build and use a backend plugin. |
| Does your plugin require alerting support? | Build and use a backend plugin. |
## Encrypt data source configuration
Data source plugins have two ways of storing custom configuration: `jsonData` and `secureJsonData`.
Users with the Viewer role can access data source configuration such as the contents of `jsonData` in cleartext. If you've enabled anonymous access, anyone who can access Grafana in their browser can see the contents of `jsonData`.
Users of [Grafana Enterprise](https://grafana.com/products/enterprise/grafana/) can restrict access to data sources to specific users and teams. For more information, refer to [Data source permissions](https://grafana.com/docs/grafana/latest/enterprise/datasource_permissions).
> **Important:** Do not use `jsonData` with sensitive data such as password, tokens, and API keys. If you need to store sensitive information, use `secureJsonData` instead.
> **Note:** You can see the settings that the current user has access to by entering `window.grafanaBootData` in the developer console of your browser.
### Store configuration in `secureJsonData`
If you need to store sensitive information, use `secureJsonData` instead of `jsonData`. Whenever the user saves the data source configuration, the secrets in `secureJsonData` are sent to the Grafana server and encrypted before they're stored.
Once you have encrypted the secure configuration, it can no longer be accessed from the browser. The only way to access secrets after they've been saved is by using the [_data source proxy_](#authenticate-using-the-data-source-proxy).
### Add secret configuration to your data source plugin
To demonstrate how you can add secrets to a data source plugin, let's add support for configuring an API key.
1. Create a new interface in `types.ts` to hold the API key:
```ts
export interface MySecureJsonData {
apiKey?: string;
}
```
1. Add type information to your `secureJsonData` object by updating the props for your `ConfigEditor` to accept the interface as a second type parameter. Access the value of the secret from the `options` prop inside your `ConfigEditor`:
```ts
interface Props extends DataSourcePluginOptionsEditorProps<MyDataSourceOptions, MySecureJsonData> {}
```
```ts
const { secureJsonData, secureJsonFields } = options;
const { apiKey } = secureJsonData;
```
> **Note:** You can do this until the user saves the configuration; when the user saves the configuration, Grafana clears the value. After that, you can use `secureJsonFields` to determine whether the property has been configured.
1. To securely update the secret in your plugin's configuration editor, update the `secureJsonData` object using the `onOptionsChange` prop:
```ts
const onAPIKeyChange = (event: ChangeEvent<HTMLInputElement>) => {
onOptionsChange({
...options,
secureJsonData: {
apiKey: event.target.value,
},
});
};
```
1. Define a component that can accept user input:
```ts
<Input
type="password"
placeholder={secureJsonFields?.apiKey ? 'configured' : ''}
value={secureJsonData.apiKey ?? ''}
onChange={onAPIKeyChange}
/>
```
1. Optional: If you want the user to be able to reset the API key, then you need to set the property to `false` in the `secureJsonFields` object:
```ts
const onResetAPIKey = () => {
onOptionsChange({
...options,
secureJsonFields: {
...options.secureJsonFields,
apiKey: false,
},
secureJsonData: {
...options.secureJsonData,
apiKey: '',
},
});
};
```
Now that users can configure secrets, the next step is to see how we can add them to our requests.
## Authenticate using the data source proxy
Once the user has saved the configuration for a data source, the secret data source configuration will no longer be available in the browser. Encrypted secrets can only be accessed on the server. So how do you add them to your request?
The Grafana server comes with a proxy that lets you define templates for your requests: _proxy routes_. Grafana sends the proxy route to the server, decrypts the secrets along with other configuration, and adds them to the request before sending it.
> **Note:** Be sure not to confuse the data source proxy with the [auth proxy]({{< relref "../../setup-grafana/configure-security/configure-authentication/auth-proxy/" >}}). The data source proxy is used to authenticate a data source, while the auth proxy is used to log into Grafana itself.
### Add a proxy route to your plugin
To forward requests through the Grafana proxy, you need to configure one or more _proxy routes_. A proxy route is a template for any outgoing request that is handled by the proxy. You can configure proxy routes in the [plugin.json](https://grafana.com/docs/grafana/latest/developers/plugins/metadata/) file.
1. Add the route to `plugin.json`:
```json
"routes": [
{
"path": "example",
"url": "https://api.example.com"
}
]
```
> **Note:** You need to restart the Grafana server every time you make a change to your `plugin.json` file.
1. In the `DataSource`, extract the proxy URL from `instanceSettings` to a class property called `url`:
```ts
export class DataSource extends DataSourceApi<MyQuery, MyDataSourceOptions> {
url?: string;
constructor(instanceSettings: DataSourceInstanceSettings<MyDataSourceOptions>) {
super(instanceSettings);
this.url = instanceSettings.url;
}
// ...
}
```
1. In the `query` method, make a request using `BackendSrv`. The first section of the URL path needs to match the `path` of your proxy route. The data source proxy replaces `this.url + routePath` with the `url` of the route. Based on our example, the URL for the request would be `https://api.example.com/v1/users`:
```ts
import { getBackendSrv } from '@grafana/runtime';
```
```ts
const routePath = '/example';
getBackendSrv().datasourceRequest({
url: this.url + routePath + '/v1/users',
method: 'GET',
});
```
### Add a dynamic proxy route to your plugin
Grafana sends the proxy route to the server, where the data source proxy decrypts any sensitive data and interpolates the template variables with the decrypted data before making the request.
To add user-defined configuration to your routes:
- Use `.JsonData` for configuration stored in `jsonData`. For example, where `projectId` is the name of a property in the `jsonData` object:
```json
"routes": [
{
"path": "example",
"url": "https://api.example.com/projects/{{ .JsonData.projectId }}"
}
]
```
- Use `.SecureJsonData` for sensitive data stored in `secureJsonData`. For example, where `password` is the name of a property in the `secureJsonData` object:
```json
"routes": [
{
"path": "example",
"url": "https://{{ .JsonData.username }}:{{ .SecureJsonData.password }}@api.example.com"
}
]
```
In addition to adding the URL to the proxy route, you can also add headers, URL parameters, and a request body.
#### Add HTTP headers to a proxy route
Here's an example of adding `name` and `content` as HTTP headers:
```json
"routes": [
{
"path": "example",
"url": "https://api.example.com",
"headers": [
{
"name": "Authorization",
"content": "Bearer {{ .SecureJsonData.apiToken }}"
}
]
}
]
```
#### Add URL parameters to a proxy route
Here's an example of adding `name` and `content` as URL parameters:
```json
"routes": [
{
"path": "example",
"url": "http://api.example.com",
"urlParams": [
{
"name": "apiKey",
"content": "{{ .SecureJsonData.apiKey }}"
}
]
}
]
```
#### Add a request body to a proxy route
Here's an example of adding `username` and `password` to the request body:
```json
"routes": [
{
"path": "example",
"url": "http://api.example.com",
"body": {
"username": "{{ .JsonData.username }}",
"password": "{{ .SecureJsonData.password }}"
}
}
]
```
### Add an OAuth 2.0 proxy route to your plugin
Since your request to each route is made server-side with OAuth 2.0 authentication, only machine-to-machine requests are supported. In order words, if you need to use a different grant than client credentials, you need to implement it yourself.
To authenticate using OAuth 2.0, add a `tokenAuth` object to the proxy route definition. If necessary, Grafana performs a request to the URL defined in `tokenAuth` to retrieve a token before making the request to the URL in your proxy route. Grafana automatically renews the token when it expires.
Any parameters defined in `tokenAuth.params` are encoded as `application/x-www-form-urlencoded` and sent to the token URL.
```json
{
"routes": [
{
"path": "api",
"url": "https://api.example.com/v1",
"tokenAuth": {
"url": "https://api.example.com/v1/oauth/token",
"params": {
"grant_type": "client_credentials",
"client_id": "{{ .SecureJsonData.clientId }}",
"client_secret": "{{ .SecureJsonData.clientSecret }}"
}
}
}
]
}
```
## Authenticate using a backend plugin
While the data source proxy supports the most common authentication methods for HTTP APIs, using proxy routes has a few limitations:
- Proxy routes only support HTTP or HTTPS.
- Proxy routes don't support custom token authentication.
If any of these limitations apply to your plugin, you need to add a [backend plugin]({{< relref "backend/" >}}). Because backend plugins run on the server, they can access decrypted secrets, which makes it easier to implement custom authentication methods.
The decrypted secrets are available from the `DecryptedSecureJSONData` field in the instance settings.
```go
func (ds *dataSource) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
instanceSettings := req.PluginContext.DataSourceInstanceSettings
if apiKey, exists := settings.DecryptedSecureJSONData["apiKey"]; exists {
// Use the decrypted API key.
}
// ...
}
```
## Forward OAuth identity for the logged-in user
If your data source uses the same OAuth provider as Grafana itself, for example using [Generic OAuth Authentication]({{< relref "../../setup-grafana/configure-security/configure-authentication/generic-oauth/" >}}), then your data source plugin can reuse the access token for the logged-in Grafana user.
To allow Grafana to pass the access token to the plugin, update the data source configuration and set the `jsonData.oauthPassThru` property to `true`. The [DataSourceHttpSettings](https://developers.grafana.com/ui/latest/index.html?path=/story/data-source-datasourcehttpsettings--basic) settings provide a toggle, the **Forward OAuth Identity** option, for this. You can also build an appropriate toggle to set `jsonData.oauthPassThru` in your data source configuration page UI.
When configured, Grafana can forward authorization HTTP headers such as `Authorization` or `X-ID-Token` to a backend data source. This information is available across the `QueryData`, `CallResource` and `CheckHealth` requests.
To get Grafana to forward the headers, create a HTTP client using the [Grafana plugin SDK for Go](https://pkg.go.dev/github.com/grafana/grafana-plugin-sdk-go/backend/httpclient) and set the `ForwardHTTPHeaders` option to `true` (by default, it's set to `false`). This package exposes request information which can be subsequently forwarded downstream and/or used directly within the plugin.
```go
func NewDatasource(settings backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) {
opts, err := settings.HTTPClientOptions()
if err != nil {
return nil, fmt.Errorf("http client options: %w", err)
}
// Important: Reuse the same client for each query to avoid using all available connections on a host.
opts.ForwardHTTPHeaders = true
cl, err := httpclient.New(opts)
if err != nil {
return nil, fmt.Errorf("httpclient new: %w", err)
}
return &Datasource{
httpClient: cl,
}, nil
}
func (ds *dataSource) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
// Necessary to keep the Context, since the injected middleware is configured there
req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://some-url", nil)
if err != nil {
return nil, fmt.Errorf("new request with context: %w", err)
}
// Authorization header will be automatically injected if oauthPassThru is configured
resp, err := ds.httpClient.Do(req)
// ...
}
```
You can see a full working plugin example here: [datasource-http-backend](https://github.com/grafana/grafana-plugin-examples/tree/main/examples/datasource-http-backend).
### Extract a header from an HTTP request
If you need to access the HTTP header information directly, you can also extract that information from the request:
```go
func (ds *dataSource) CheckHealth(ctx context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) {
token := strings.Fields(req.GetHTTPHeader(backend.OAuthIdentityTokenHeaderName))
var (
tokenType = token[0]
accessToken = token[1]
)
idToken := req.GetHTTPHeader(backend.OAuthIdentityIDTokenHeaderName) // present if user's token includes an ID token
// ...
return &backend.CheckHealthResult{Status: backend.HealthStatusOk}, nil
}
func (ds *dataSource) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
token := strings.Fields(req.GetHTTPHeader(backend.OAuthIdentityTokenHeaderName))
var (
tokenType = token[0]
accessToken = token[1]
)
idToken := req.GetHTTPHeader(backend.OAuthIdentityIDTokenHeaderName)
for _, q := range req.Queries {
// ...
}
}
func (ds *dataSource) CallResource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error {
token := req.GetHTTPHeader(backend.OAuthIdentityTokenHeaderName)
idToken := req.GetHTTPHeader(backend.OAuthIdentityIDTokenHeaderName)
// ...
}
```
## Work with cookies
### Forward cookies for the logged-in user
Your data source plugin can forward cookies for the logged-in Grafana user to the data source. Use the [DataSourceHttpSettings](https://developers.grafana.com/ui/latest/index.html?path=/story/data-source-datasourcehttpsettings--basic) component on the data source's configuration page. It provides the **Allowed cookies** option, where you can specify the cookie names.
When configured, as with [authorization headers](#forward-oauth-identity-for-the-logged-in-user), these cookies are automatically injected if you use the SDK HTTP client.
### Extract cookies for the logged-in user
You can also extract the cookies in the `QueryData`, `CallResource` and `CheckHealth` requests if required.
**`QueryData`**
```go
func (ds *dataSource) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
cookies:= req.GetHTTPHeader(backend.CookiesHeaderName)
// ...
}
```
**`CallResource`**
```go
func (ds *dataSource) CallResource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error {
cookies:= req.GetHTTPHeader(backend.CookiesHeaderName)
// ...
}
```
**`CheckHealth`**
```go
func (ds *dataSource) CheckHealth(ctx context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) {
cookies:= req.GetHTTPHeader(backend.CookiesHeaderName)
// ...
}
```
## Forward user header for the logged-in user
When [send_user_header]({{< relref "../../setup-grafana/configure-grafana/_index.md#send_user_header" >}}) is enabled, Grafana passes the user header to the plugin using the `X-Grafana-User` header. You can forward this header as well as [authorization headers](#forward-oauth-identity-for-the-logged-in-user) or [configured cookies](#forward-cookies-for-the-logged-in-user).
**`QueryData`**
```go
func (ds *dataSource) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
u := req.GetHTTPHeader("X-Grafana-User")
// ...
}
```
**`CallResource`**
```go
func (ds *dataSource) CallResource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error {
u := req.GetHTTPHeader("X-Grafana-User")
// ...
}
```
**`CheckHealth`**
```go
func (ds *dataSource) CheckHealth(ctx context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) {
u := req.GetHTTPHeader("X-Grafana-User")
// ...
}
```

View File

@@ -1,110 +0,0 @@
---
title: Add distributed tracing for backend plugins
---
# Add distributed tracing for backend plugins
> **Note:** This feature requires at least Grafana 9.5.0, and your plugin needs to be built at least with grafana-plugins-sdk-go v0.157.0. If you run a plugin with tracing features on an older version of Grafana, tracing is disabled.
Distributed tracing allows backend plugin developers to create custom spans in their plugins, and send them to the same endpoint and with the same propagation format as the main Grafana instance. The tracing context is also propagated from the Grafana instance to the plugin, so the plugin's spans will be correlated to the correct trace.
## Plugin configuration
Plugin tracing must be enabled manually on a per-plugin basis, by specifying `tracing = true` in the plugin's config section:
```ini
[plugin.myorg-myplugin-datasource]
tracing = true
```
## OpenTelemetry configuration in Grafana
Grafana supports [OpenTelemetry](https://opentelemetry.io/) for distributed tracing. If Grafana is configured to use a deprecated tracing system (Jaeger or OpenTracing), then tracing is disabled in the plugin provided by the SDK and configured when calling `datasource.Manage | app.Manage`.
OpenTelemetry must be enabled and configured for the Grafana instance. Please refer to the [Grafana configuration documentation](
{{< relref "../../setup-grafana/configure-grafana/#tracingopentelemetry" >}}) for more information.
Refer to the [OpenTelemetry Go SDK](https://pkg.go.dev/go.opentelemetry.io/otel) for in-depth documentation about all the features provided by OpenTelemetry.
> **Note:** If tracing is disabled in Grafana, `backend.DefaultTracer()` returns a no-op tracer.
## Implement tracing in your plugin
> **Note:** Make sure you are using at least grafana-plugin-sdk-go v0.157.0. You can update with `go get -u github.com/grafana/grafana-plugin-sdk-go`.
### Configure a global tracer
When OpenTelemetry tracing is enabled on the main Grafana instance and tracing is enabled for a plugin, the OpenTelemetry endpoint address and propagation format is passed to the plugin during startup. These parameters are used to configure a global tracer.
1. Use `datasource.Manage` or `app.Manage` to run your plugin to automatically configure the global tracer. Specify any custom attributes for the default tracer using `CustomAttributes`:
```go
func main() {
if err := datasource.Manage("MY_PLUGIN_ID", plugin.NewDatasource, datasource.ManageOpts{
TracingOpts: tracing.Opts{
// Optional custom attributes attached to the tracer's resource.
// The tracer will already have some SDK and runtime ones pre-populated.
CustomAttributes: []attribute.KeyValue{
attribute.String("my_plugin.my_attribute", "custom value"),
},
},
}); err != nil {
log.DefaultLogger.Error(err.Error())
os.Exit(1)
}
}
```
1. Once you have configured tracing, use the global tracer like this:
```go
tracing.DefaultTracer()
```
This returns an [OpenTelemetry `trace.Tracer`](https://pkg.go.dev/go.opentelemetry.io/otel/trace#Tracer) for creating spans.
**Example:**
```go
func (d *Datasource) query(ctx context.Context, pCtx backend.PluginContext, query backend.DataQuery) (backend.DataResponse, error) {
ctx, span := tracing.DefaultTracer().Start(
ctx,
"query processing",
trace.WithAttributes(
attribute.String("query.ref_id", query.RefID),
attribute.String("query.type", query.QueryType),
attribute.Int64("query.max_data_points", query.MaxDataPoints),
attribute.Int64("query.interval_ms", query.Interval.Milliseconds()),
attribute.Int64("query.time_range.from", query.TimeRange.From.Unix()),
attribute.Int64("query.time_range.to", query.TimeRange.To.Unix()),
),
)
defer span.End()
log.DefaultLogger.Debug("query", "traceID", trace.SpanContextFromContext(ctx).TraceID())
// ...
}
```
### Tracing gRPC calls
When tracing is enabled, a new span is created automatically for each gRPC call (`QueryData`, `CheckHealth`, etc.), both on Grafana's side and on the plugin's side. The plugin SDK also injects the trace context into the `context.Context` that is passed to those methods.
You can retrieve the [trace.SpanContext](https://pkg.go.dev/go.opentelemetry.io/otel/trace#SpanContext) with `tracing.SpanContextFromContext` by passing the original `context.Context` to it:
```go
func (d *Datasource) query(ctx context.Context, pCtx backend.PluginContext, query backend.DataQuery) (backend.DataResponse, error) {
spanCtx := trace.SpanContextFromContext(ctx)
traceID := spanCtx.TraceID()
// ...
}
```
### Tracing HTTP requests
When tracing is enabled, a `TracingMiddleware` is also added to the default middleware stack to all HTTP clients created using the `httpclient.New` or `httpclient.NewProvider`, unless you specify custom middleware. This middleware creates spans for each outgoing HTTP request and provides some useful attributes and events related to the request's lifecycle.
## Plugin example
Refer to the [datasource-http-backend plugin example](https://github.com/grafana/grafana-plugin-examples/tree/main/examples/datasource-http-backend) for a complete example of a plugin with full distributed tracing support.

View File

@@ -1,73 +0,0 @@
---
title: Add query editor help
---
# Add query editor help
Query editors support the addition of a help component to display examples of potential queries. When the user clicks on one of the examples, the query editor is automatically updated. This helps the user to make faster queries.
1. In the `src` directory of your plugin, create a file `QueryEditorHelp.tsx` with the following content:
```ts
import React from 'react';
import { QueryEditorHelpProps } from '@grafana/data';
export default (props: QueryEditorHelpProps) => {
return <h2>My cheat sheet</h2>;
};
```
1. Configure the plugin to use `QueryEditorHelp`:
```ts
import QueryEditorHelp from './QueryEditorHelp';
```
```ts
export const plugin = new DataSourcePlugin<DataSource, MyQuery, MyDataSourceOptions>(DataSource)
.setConfigEditor(ConfigEditor)
.setQueryEditor(QueryEditor)
.setQueryEditorHelp(QueryEditorHelp);
```
1. Create a few examples of potential queries:
```ts
import React from 'react';
import { QueryEditorHelpProps, DataQuery } from '@grafana/data';
const examples = [
{
title: 'Addition',
expression: '1 + 2',
label: 'Add two integers',
},
{
title: 'Subtraction',
expression: '2 - 1',
label: 'Subtract an integer from another',
},
];
export default (props: QueryEditorHelpProps) => {
return (
<div>
<h2>Cheat Sheet</h2>
{examples.map((item, index) => (
<div className="cheat-sheet-item" key={index}>
<div className="cheat-sheet-item__title">{item.title}</div>
{item.expression ? (
<div
className="cheat-sheet-item__example"
onClick={(e) => props.onClickExample({ refId: 'A', queryText: item.expression } as DataQuery)}
>
<code>{item.expression}</code>
</div>
) : null}
<div className="cheat-sheet-item__label">{item.label}</div>
</div>
))}
</div>
);
};
```

View File

@@ -1,30 +0,0 @@
---
title: Add support for annotations
---
# Add support for annotations
You can add support to your plugin for annotations that will insert information into Grafana alerts. This guide explains how to add support for [annotations]({{< relref "../../dashboards/build-dashboards/annotate-visualizations/#querying-other-data-sources " >}}) to a data source plugin.
## Support annotations in your data source plugin
To enable annotations, simply add two lines of code to your plugin. Grafana uses your default query editor for editing annotation queries.
1. Add `"annotations": true` to the [plugin.json]({{< relref "metadata/" >}}) file to let Grafana know that your plugin supports annotations.
**In `plugin.json`:**
```json
{
"annotations": true
}
```
2. In `datasource.ts`, override the `annotations` property from `DataSourceApi` (or `DataSourceWithBackend` for backend data sources). For the default behavior, set `annotations` to an empty object.
**In `datasource.ts`:**
```ts
annotations: {
}
```

View File

@@ -1,70 +0,0 @@
---
title: Add features to Explore queries
---
# Add features for Explore queries
[Explore]({{< relref "../../explore/" >}}) allows users can make ad-hoc queries without the use of a dashboard. This is useful when they want to troubleshoot or learn more about the data.
Your data source supports Explore by default and uses the existing query editor for the data source. This guide explains how to extend functionality for Explore queries in a data source plugin.
## Add an Explore-specific query editor
To extend Explore functionality for your data source, define an Explore-specific query editor.
1. Create a file `ExploreQueryEditor.tsx` in the `src` directory of your plugin, with content similar to this:
```ts
import React from 'react';
import { QueryEditorProps } from '@grafana/data';
import { QueryField } from '@grafana/ui';
import { DataSource } from './DataSource';
import { MyQuery, MyDataSourceOptions } from './types';
type Props = QueryEditorProps<DataSource, MyQuery, MyDataSourceOptions>;
export default (props: Props) => {
return <h2>My Explore-specific query editor</h2>;
};
```
1. Modify your base query editor in `QueryEditor.tsx` to render the Explore-specific query editor. For example:
```ts
// [...]
import { CoreApp } from '@grafana/data';
import ExploreQueryEditor from './ExploreQueryEditor';
type Props = QueryEditorProps<DataSource, MyQuery, MyDataSourceOptions>;
export default (props: Props) => {
const { app } = props;
switch (app) {
case CoreApp.Explore:
return <ExploreQueryEditor {...props} />;
default:
return <div>My base query editor</div>;
}
};
```
## Select a preferred visualization type
By default, Explore should select an appropriate and useful visualization for your data. It can figure out whether the returned data is time series data or logs or something else, and creates the right type of visualization.
However, if you want a custom visualization, you can add a hint to your returned data frame by setting the `meta' attribute to `preferredVisualisationType`.
Construct a data frame with specific metadata like this:
```
const firstResult = new MutableDataFrame({
fields: [...],
meta: {
preferredVisualisationType: 'logs',
},
});
```
For possible options, refer to [PreferredVisualisationType](https://github.com/grafana/grafana/blob/main/packages/grafana-data/src/types/data.ts#L25).

View File

@@ -1,198 +0,0 @@
---
title: Add support for variables in plugins
---
# Add support for variables in plugins
Variables are placeholders for values, and you can use them to create templated queries, and dashboard or panel links. For more information on variables, refer to [Templates and variables]({{< relref "../../dashboards/variables/" >}}).
In this guide, you'll see how you can turn a query string like this:
```sql
SELECT * FROM services WHERE id = "$service"
```
into
```sql
SELECT * FROM services WHERE id = "auth-api"
```
Grafana provides a couple of helper functions to interpolate variables in a string template. Let's see how you can use them in your plugin.
## Interpolate variables in panel plugins
For panels, the `replaceVariables` function is available in the `PanelProps`.
Add `replaceVariables` to the argument list, and pass a user-defined template string to it:
```ts
export function SimplePanel({ options, data, width, height, replaceVariables }: Props) {
const query = replaceVariables('Now displaying $service');
return <div>{query}</div>;
}
```
## Interpolate variables in data source plugins
For data sources, you need to use the `getTemplateSrv`, which returns an instance of `TemplateSrv`.
1. Import `getTemplateSrv` from the `runtime` package:
```ts
import { getTemplateSrv } from '@grafana/runtime';
```
1. In your `query` method, call the `replace` method with a user-defined template string:
```ts
async query(options: DataQueryRequest<MyQuery>): Promise<DataQueryResponse> {
const query = getTemplateSrv().replace('SELECT * FROM services WHERE id = "$service"', options.scopedVars);
const data = makeDbQuery(query);
return { data };
}
```
## Format multi-value variables
When a user selects multiple values for a variable, the value of the interpolated variable depends on the [variable format]({{< relref "../../dashboards/variables/variable-syntax/#advanced-variable-format-options" >}}).
A data source plugin can define the default format option when no format is specified by adding a third argument to the interpolation function.
Let's change the SQL query to use CSV format by default:
```ts
getTemplateSrv().replace('SELECT * FROM services WHERE id IN ($service)', options.scopedVars, 'csv');
```
Now, when users write `$service`, the query looks like this:
```sql
SELECT * FROM services WHERE id IN (admin,auth,billing)
```
For more information on the available variable formats, refer to [Advanced variable format options]({{< relref "../../dashboards/variables/variable-syntax/#advanced-variable-format-options" >}}).
## Set a variable from your plugin
Not only can you read the value of a variable, you can also update the variable from your plugin. Use `locationService.partial(query, replace)`.
The following example shows how to update a variable called `service`.
- `query` contains the query parameters you want to update. The query parameters that control variables are prefixed with `var-`.
- `replace: true` tells Grafana to update the current URL state rather than creating a new history entry.
```ts
import { locationService } from '@grafana/runtime';
```
```ts
locationService.partial({ 'var-service': 'billing' }, true);
```
> **Note:** Grafana queries your data source whenever you update a variable. Excessive updates to variables can slow down Grafana and lead to a poor user experience.
## Add support for query variables to your data source
A [query variable]({{< relref "../../dashboards/variables/add-template-variables/#add-a-query-variable" >}}) is a type of variable that allows you to query a data source for the values. By adding support for query variables to your data source plugin, users can create dynamic dashboards based on data from your data source.
Let's start by defining a query model for the variable query:
```ts
export interface MyVariableQuery {
namespace: string;
rawQuery: string;
}
```
For a data source to support query variables, override the `metricFindQuery` in your `DataSourceApi` class. The `metricFindQuery` function returns an array of `MetricFindValue` which has a single property, `text`:
```ts
async metricFindQuery(query: MyVariableQuery, options?: any) {
// Retrieve DataQueryResponse based on query.
const response = await this.fetchMetricNames(query.namespace, query.rawQuery);
// Convert query results to a MetricFindValue[]
const values = response.data.map(frame => ({ text: frame.name }));
return values;
}
```
> **Note:** By default, Grafana provides a basic query model and editor for simple text queries. If that's all you need, then leave the query type as `string`:
```ts
async metricFindQuery(query: string, options?: any)
```
Let's create a custom query editor to allow the user to edit the query model.
1. Create a `VariableQueryEditor` component:
```ts
import React, { useState } from 'react';
import { MyVariableQuery } from './types';
interface VariableQueryProps {
query: MyVariableQuery;
onChange: (query: MyVariableQuery, definition: string) => void;
}
export const VariableQueryEditor: React.FC<VariableQueryProps> = ({ onChange, query }) => {
const [state, setState] = useState(query);
const saveQuery = () => {
onChange(state, `${state.query} (${state.namespace})`);
};
const handleChange = (event: React.FormEvent<HTMLInputElement>) =>
setState({
...state,
[event.currentTarget.name]: event.currentTarget.value,
});
return (
<>
<div className="gf-form">
<span className="gf-form-label width-10">Namespace</span>
<input
name="namespace"
className="gf-form-input"
onBlur={saveQuery}
onChange={handleChange}
value={state.namespace}
/>
</div>
<div className="gf-form">
<span className="gf-form-label width-10">Query</span>
<input
name="rawQuery"
className="gf-form-input"
onBlur={saveQuery}
onChange={handleChange}
value={state.rawQuery}
/>
</div>
</>
);
};
```
Grafana saves the query model whenever one of the text fields loses focus (`onBlur`) and then previews the values returned by `metricFindQuery`.
The second argument to `onChange` allows you to set a text representation of the query that will appear next to the name of the variable in the variables list.
1. Configure your plugin to use the query editor:
```ts
import { VariableQueryEditor } from './VariableQueryEditor';
export const plugin = new DataSourcePlugin<DataSource, MyQuery, MyDataSourceOptions>(DataSource)
.setQueryEditor(QueryEditor)
.setVariableQueryEditor(VariableQueryEditor);
```
That's it! You can now try out the plugin by adding a [query variable]({{< relref "../../dashboards/variables/add-template-variables/#add-a-query-variable" >}}) to your dashboard.

View File

@@ -1,75 +0,0 @@
---
aliases:
- ../../plugins/developing/backend-plugins-guide/
keywords:
- grafana
- plugins
- backend
- plugin
- backend-plugins
- documentation
title: Backend plugins
---
# Backend plugins
Grafana added support for plugins in version 3.0 and this enabled the Grafana community to create panel plugins and data source plugins. It was wildly successful and has made Grafana much more useful as you can integrate it with anything and do any type of custom visualization that you want.
However, one limitation with these plugins are that they execute on the client-side (in the browser) which makes it hard to support certain use cases/features, e.g. enable Grafana Alerting for data sources. Grafana v7.0 adds official support for backend plugins which removes this limitation. At the same time it gives plugin developers the possibility to extend Grafana in new and interesting ways, with code running in the backend (server side).
We use the term _backend plugin_ to denote that a plugin has a backend component. Still, normally a backend plugin requires frontend components as well. This is for example true for backend data source plugins which normally need configuration and query editor components implemented for the frontend.
Data source plugins can be extended with a backend component. In the future we plan to support additional types and possibly new kinds of plugins, such as notifiers for Grafana Alerting and custom authentication to name a few.
## Use cases for implementing a backend plugin
The following examples gives you an idea of why you'd consider implementing a backend plugin:
- Enable [Grafana Alerting]({{< relref "../../../alerting/" >}}) for data sources.
- Connect to non-HTTP services that normally can't be connected to from a web browser, e.g. SQL database servers.
- Keep state between users, e.g. query caching for data sources.
- Use custom authentication methods and/or authorization checks that aren't supported in Grafana.
- Use a custom data source request proxy, see [Resources]({{< relref "#resources" >}}).
## Grafanas backend plugin system
The Grafana backend plugin system is based on the [go-plugin library by HashiCorp](https://github.com/hashicorp/go-plugin). The Grafana server launches each backend plugin as a subprocess and communicates with it over [gRPC](https://grpc.io/). This approach has a number of benefits:
- Plugins cant crash your grafana process: a panic in a plugin doesnt panic the server.
- Plugins are easy to develop: just write a Go application and run `go build` (or use any other language which supports gRPC).
- Plugins can be relatively secure: The plugin only has access to the interfaces and arguments that are given to it, not to the entire memory space of the process.
Grafana's backend plugin system exposes a couple of different capabilities, or building blocks, that a backend plugin can implement:
- Query data
- Resources
- Health checks
- Collect metrics
### Query data
The query data capability allows a backend plugin to handle data source queries that are submitted from a [dashboard]({{< relref "../../../dashboards/" >}}), [Explore]({{< relref "../../../explore/" >}}) or [Grafana Alerting]({{< relref "../../../alerting/" >}}). The response contains [data frames]({{< relref "../data-frames/" >}}), which are used to visualize metrics, logs, and traces. The query data capability is required to implement for a backend data source plugin.
### Resources
The resources capability allows a backend plugin to handle custom HTTP requests sent to the Grafana HTTP API and respond with custom HTTP responses. Here, the request and response formats can vary, e.g. JSON, plain text, HTML or static resources (files, images) etc. Compared to the query data capability where the response contains data frames, resources give the plugin developer a lot of flexibility for extending and open up Grafana for new and interesting use cases.
Examples of use cases for implementing resources:
- Implement a custom data source proxy in case certain authentication/authorization or other requirements are required/needed that are not supported in Grafana's [built-in data proxy]({{< relref "../../http_api/data_source/#data-source-proxy-calls" >}}).
- Return data or information in a format suitable to use within a data source query editor to provide auto-complete functionality.
- Return static resources, such as images or files.
- Send a command to a device, such as a micro controller or IOT device.
- Request information from a device, such as a micro controller or IOT device.
- Extend Grafana's HTTP API with custom resources, methods and actions.
- Use [chunked transfer encoding](https://en.wikipedia.org/wiki/Chunked_transfer_encoding) to return large data responses in chunks or to enable "basic" streaming capabilities.
### Health checks
The health checks capability allows a backend plugin to return the status of the plugin. For data source backend plugins the health check will automatically be called when you do _Save & Test_ in the UI when editing a data source. A plugin's health check endpoint is exposed in the Grafana HTTP API and allows external systems to continuously poll the plugin's health to make sure it's running and working as expected.
### Collect metrics
A backend plugin can collect and return runtime, process and custom metrics using the text-based Prometheus [exposition format](https://prometheus.io/docs/instrumenting/exposition_formats/). If youre using the [Grafana Plugin SDK for Go]({{< relref "grafana-plugin-sdk-for-go/" >}}) to implement your backend plugin, then the [Prometheus instrumentation library for Go applications](https://github.com/prometheus/client_golang) is built-in, and gives you Go runtime metrics and process metrics out of the box. By using the [Prometheus instrumentation library](https://github.com/prometheus/client_golang) you can add custom metrics to instrument your backend plugin.
A metrics endpoint (`/api/plugins/<plugin id>/metrics`) for a plugin is available in the Grafana HTTP API and allows a Prometheus instance to be configured to scrape the metrics.

View File

@@ -1,26 +0,0 @@
---
keywords:
- grafana
- plugins
- backend
- plugin
- backend-plugins
- sdk
- documentation
title: Grafana Plugin SDK for Go
---
# Grafana plugin SDK for Go
The Grafana plugin SDK for Go enables building Grafana backend plugins using [Go](https://golang.org/). The SDK provides a high-level framework with APIs, utilities and tooling that abstract away the details of the [plugin protocol]({{< relref "plugin-protocol/" >}}) and RPC communication so plugin developers do not need to manage either.
The [github.com/grafana/grafana-plugin-sdk-go](https://pkg.go.dev/mod/github.com/grafana/grafana-plugin-sdk-go?tab=overview) is a Go module that provides a set of [Go packages](https://pkg.go.dev/mod/github.com/grafana/grafana-plugin-sdk-go?tab=packages) that can be used to implement a backend plugin.
## Versioning
The SDK is still in development. The [plugin protocol]({{< relref "plugin-protocol/" >}}) between Grafana and the plugin SDK is versioned separately and considered stable. However, there might be breaking changes introduced in the SDK. This means that plugins using an older version of the SDK should still work with Grafana, but might lose out on new features and capabilities introduced in the SDK.
## See also
- [Source code](https://github.com/grafana/grafana-plugin-sdk-go)
- [Go reference documentation](https://pkg.go.dev/github.com/grafana/grafana-plugin-sdk-go)

View File

@@ -1,34 +0,0 @@
---
keywords:
- grafana
- plugins
- backend
- plugin
- backend-plugins
- documentation
title: Plugin protocol
---
# Plugin protocol
Theres a physical wire protocol that Grafana server uses to communicate with backend plugins. This is the contract between Grafana and backend plugins, that must be agreed upon for Grafana and a backend plugin to be able to communicate with each other. The plugin protocol is built on [gRPC](https://grpc.io/) and is defined in [Protocol Buffers (a.k.a., protobuf)](https://developers.google.com/protocol-buffers).
We advise for backend plugins to not be implemented directly against this protocol. Instead, prefer to use the [Grafana Plugin SDK for Go]({{< relref "grafana-plugin-sdk-for-go/" >}}) that implements this protocol and provides higher level APIs.
The plugin protocol is available in the [GitHub repository](https://github.com/grafana/grafana-plugin-sdk-go/blob/master/proto/backend.proto). The plugin protocol lives in the [Grafana Plugin SDK for Go]({{< relref "grafana-plugin-sdk-for-go/" >}}) since Grafana itself uses parts of the SDK as a dependency.
## Versioning
Additions of services, messages and fields in the latest version of the plugin protocol are expected to happen, but should not introduce any breaking changes. If breaking changes to the plugin protocol is needed, a new major version of the plugin protocol will be created and released together with a new major Grafana release. Grafana will then support both the old and the new plugin protocol for some time to make sure existing backend plugins continue to work.
Because Grafana maintains the plugin protocol, the plugin protocol attempts to follow Grafana's versioning, However, that doesn't automatically mean that a new major version of the plugin protocol is created when a new major release of Grafana is released.
## Writing plugins without Go
If you want to write a backend plugin in another language than Go, then its possible as long as the language supports [gRPC](https://grpc.io/). However, writing a plugin in Go is recommended and has several advantages that should be carefully taken into account before proceeding:
- There's an official [SDK]({{< relref "grafana-plugin-sdk-for-go/" >}}) available.
- Single binary as the compiled output.
- Building and compiling for multiple platforms is easy.
- A statically compiled binary (in most cases) doesn't require any additional dependencies installed on the target platform enabling it to run “everywhere”.
- Small footprint in regards to binary size and resource usage.

View File

@@ -1,148 +0,0 @@
---
title: Build a logs data source plugin
---
# Build a logs data source plugin
Grafana data source plugins support metrics, logs, and other data types. The steps to build a logs data source plugin are largely the same as for a metrics data source, but there are a few differences which we will explain in this guide.
## Before you begin
This guide assumes that you're already familiar with how to [Build a data source plugin](/tutorials/build-a-data-source-plugin/) for metrics. We recommend that you review this material before continuing.
## Add logs support to your data source
To add logs support to an existing data source, you need to:
1. Enable logs support
1. Construct the log data
When these steps are done, then you can improve the user experience with one or more [optional features](#enhance-your-logs-data-source-plugin-with-optional-features).
### Step 1: Enable logs support
Tell Grafana that your data source plugin can return log data, by adding `"logs": true` to the [plugin.json]({{< relref "metadata/" >}}) file.
```json
{
"logs": true
}
```
### Step 2: Construct the log data
As it does with metrics data, Grafana expects your plugin to return log data as a [data frame]({{< relref "data-frames/" >}}).
To return log data, return a data frame with at least one time field and one text field from the data source's `query` method.
**Example:**
```ts
const frame = new MutableDataFrame({
refId: query.refId,
fields: [
{ name: 'time', type: FieldType.time },
{ name: 'content', type: FieldType.string },
],
});
frame.add({ time: 1589189388597, content: 'user registered' });
frame.add({ time: 1589189406480, content: 'user logged in' });
```
That's all you need to start returning log data from your data source. Go ahead and try it out in [Explore]({{< relref "../../explore/" >}}) or by adding a [Logs panel]({{< relref "../../panels-visualizations/visualizations/logs/" >}}).
Congratulations, you just wrote your first logs data source plugin! Next, let's look at a couple of features that can further improve the experience for the user.
## Enhance your logs data source plugin with optional features
Add visualization type hints, labels, and other optional features to logs.
### Add a preferred visualization type hint to the data frame
To make sure Grafana recognizes data as logs and shows logs visualization automatically in Explore, set `meta.preferredVisualisationType` to `'logs'` in the returned data frame. See [Selecting preferred visualisation section]({{< relref "add-support-for-explore-queries/#selecting-preferred-visualisation" >}})
**Example:**
```ts
const frame = new MutableDataFrame({
refId: query.refId,
meta: {
preferredVisualisationType: 'logs',
},
fields: [
{ name: 'time', type: FieldType.time },
{ name: 'content', type: FieldType.string },
],
});
```
### Add labels to your logs
Many log systems let you query logs based on metadata, or _labels_, to help filter log lines.
Add labels to a stream of logs by setting the `labels` property on the Field.
**Example**:
```ts
const frame = new MutableDataFrame({
refId: query.refId,
fields: [
{ name: 'time', type: FieldType.time },
{ name: 'content', type: FieldType.string, labels: { filename: 'file.txt' } },
],
});
frame.add({ time: 1589189388597, content: 'user registered' });
frame.add({ time: 1589189406480, content: 'user logged in' });
```
### Extract detected fields from your logs
Add additional information about each log line by supplying more data frame fields.
If a data frame has more than one text field, then Grafana assumes the first field in the data frame to be the actual log line. Grafana treats subsequent text fields as [detected fields]({{< relref "../../explore/#labels-and-detected-fields" >}}).
Any number of custom fields can be added to your data frame; Grafana comes with two dedicated fields: `levels` and `id`.
#### Levels
To set the level for each log line, add a `level` field.
**Example:**
```ts
const frame = new MutableDataFrame({
refId: query.refId,
fields: [
{ name: 'time', type: FieldType.time },
{ name: 'content', type: FieldType.string, labels: { filename: 'file.txt' } },
{ name: 'level', type: FieldType.string },
],
});
frame.add({ time: 1589189388597, content: 'user registered', level: 'info' });
frame.add({ time: 1589189406480, content: 'unknown error', level: 'error' });
```
#### 'id' for assigning unique identifiers to log lines
By default, Grafana offers basic support for deduplicating log lines. You can improve the support by adding an `id` field to explicitly assign identifiers to each log line.
**Example:**
```ts
const frame = new MutableDataFrame({
refId: query.refId,
fields: [
{ name: 'time', type: FieldType.time },
{ name: 'content', type: FieldType.string, labels: { filename: 'file.txt' } },
{ name: 'level', type: FieldType.string },
{ name: 'id', type: FieldType.string },
],
});
frame.add({ time: 1589189388597, content: 'user registered', level: 'info', id: 'd3b07384d113edec49eaa6238ad5ff00' });
frame.add({ time: 1589189406480, content: 'unknown error', level: 'error', id: 'c157a79031e1c40f85931829bc5fc552' });
```

View File

@@ -1,151 +0,0 @@
---
title: Build a streaming data source plugin
---
# Build a streaming data source plugin
In Grafana, you can set your dashboards to automatically refresh at a certain interval, no matter what data source you use. Unfortunately, this means that your queries are requesting all the data to be sent again, regardless of whether the data has actually changed. Adding streaming to a plugin helps reduce queries so your dashboard is only updated when new data becomes available.
## Before you begin
This guide assumes that you're already familiar with how to [Build a data source plugin](/tutorials/build-a-data-source-plugin/).
Grafana uses [RxJS](https://rxjs.dev/) to continuously send data from a data source to a panel visualization.
> **Note:** To learn more about RxJs, refer to the [RxJS documentation](https://rxjs.dev/guide/overview).
## Add streaming to your data source
Enable streaming for your data source plugin to update your dashboard when new data becomes available.
For example, a streaming data source plugin can connect to a websocket, or subscribe to a message bus, and update the visualization whenever a new message is available.
### Step 1: Edit the `plugin.json` file
Enable streaming for your data source in the `plugin.json` file.
```json
{
"streaming": true
}
```
### Step 2: Change the signature of the `query` method
Modify the signature of the `query` method to return an `Observable` from the `rxjs` package. Make sure you remove the `async` keyword.
```ts
import { Observable } from 'rxjs';
```
```ts
query(options: DataQueryRequest<MyQuery>): Observable<DataQueryResponse> {
// ...
}
```
### Step 3: Create an `Observable` instance for each query
Create an `Observable` instance for each query, and then combine them all using the `merge` function from the `rxjs` package.
```ts
import { Observable, merge } from 'rxjs';
```
```ts
const observables = options.targets.map((target) => {
return new Observable<DataQueryResponse>((subscriber) => {
// ...
});
});
return merge(...observables);
```
### Step 4: Create a `CircularDataFrame` instance
In the `subscribe` function, create a `CircularDataFrame` instance.
```ts
import { CircularDataFrame } from '@grafana/data';
```
```ts
const frame = new CircularDataFrame({
append: 'tail',
capacity: 1000,
});
frame.refId = query.refId;
frame.addField({ name: 'time', type: FieldType.time });
frame.addField({ name: 'value', type: FieldType.number });
```
Circular data frames have a limited capacity. When a circular data frame reaches its capacity, the oldest data point is removed.
### Step 5: Send the updated data frame
Use `subscriber.next()` to send the updated data frame whenever you receive new updates.
```ts
import { LoadingState } from '@grafana/data';
```
```ts
const intervalId = setInterval(() => {
frame.add({ time: Date.now(), value: Math.random() });
subscriber.next({
data: [frame],
key: query.refId,
state: LoadingState.Streaming,
});
}, 500);
return () => {
clearInterval(intervalId);
};
```
> **Note:** In practice, you'd call `subscriber.next` as soon as you receive new data from a websocket or a message bus. In the example above, data is being received every 500 milliseconds.
### Example code for final `query` method
```ts
query(options: DataQueryRequest<MyQuery>): Observable<DataQueryResponse> {
const streams = options.targets.map(target => {
const query = defaults(target, defaultQuery);
return new Observable<DataQueryResponse>(subscriber => {
const frame = new CircularDataFrame({
append: 'tail',
capacity: 1000,
});
frame.refId = query.refId;
frame.addField({ name: 'time', type: FieldType.time });
frame.addField({ name: 'value', type: FieldType.number });
const intervalId = setInterval(() => {
frame.add({ time: Date.now(), value: Math.random() });
subscriber.next({
data: [frame],
key: query.refId,
state: LoadingState.Streaming,
});
}, 100);
return () => {
clearInterval(intervalId);
};
});
});
return merge(...streams);
}
```
One limitation with this example is that the panel visualization is cleared every time you update the dashboard. If you have access to historical data, you can add it, or _backfill_ it, to the data frame before the first call to `subscriber.next()`.
For another example of a streaming plugin, refer to the [streaming websocket example](https://github.com/grafana/grafana-plugin-examples/tree/main/examples/datasource-streaming-websocket) on GitHub.

View File

@@ -1,27 +0,0 @@
---
description: How-to topics for plugin development
title: Create a plugin
---
# Create a Grafana plugin
This section contains how-to topics for developing Grafana plugins.
- [Build a Grafana plugin](https://grafana.github.io/plugin-tools/docs/creating-a-plugin)
- [Build a panel plugin](https://grafana.com/tutorials/build-a-panel-plugin/)
- [Build a data source plugin](https://grafana.com/tutorials/build-a-data-source-plugin/)
- [Build a data source backend plugin](https://grafana.com/tutorials/build-a-data-source-backend-plugin/)
- [Build a logs data source plugin]({{< relref "../build-a-logs-data-source-plugin.md">}})
- [Build a streaming data source plugin]({{< relref "../build-a-streaming-data-source-plugin.md">}})
- Extend a Grafana plugin
- [Add annotations]({{< relref "add-support-for-annotations.md">}})
- [Add anonymous usage reporting]({{< relref "add-anonymous-usage-reporting.md">}})
- [Add authentication for a data source plugin]({{< relref "add-authentication-for-data-source-plugins.md">}})
- [Add Explore queries]({{< relref "add-support-for-explore-queries.md">}})
- [Add query editor help]({{< relref "add-query-editor-help.md">}})
- [Add variables]({{< relref "add-support-for-variables.md">}})
- [Create panel option editors]({{< relref "custom-panel-option-editors.md">}})
- [Sign a plugin]({{< relref "sign-a-plugin.md">}})
- [Automate development with CI](https://grafana.github.io/plugin-tools/docs/ci)
- [Create nested plugins](https://grafana.github.io/plugin-tools/docs/nested-plugins)
- [Extend configurations](https://grafana.github.io/plugin-tools/docs/advanced-configuration)

View File

@@ -1,118 +0,0 @@
---
title: Custom panel option editors
---
# Custom panel option editors
The Grafana plugin platform comes with a range of editors that allow your users to customize a panel. The standard editors cover the most common types of options, such as text input and boolean switches. If you don't find the editor you're looking for, you can build your own. In this guide, you'll learn how to build your own panel option editor.
The simplest editor is a React component that accepts two props: `value` and `onChange`. `value` contains the current value of the option, and `onChange` updates it.
The editor in the example below lets the user toggle a boolean value by clicking a button:
**SimpleEditor.tsx**
```ts
import React from 'react';
import { Button } from '@grafana/ui';
import { StandardEditorProps } from '@grafana/data';
export const SimpleEditor: React.FC<StandardEditorProps<boolean>> = ({ value, onChange }) => {
return <Button onClick={() => onChange(!value)}>{value ? 'Disable' : 'Enable'}</Button>;
};
```
To use a custom panel option editor, use the `addCustomEditor` on the `OptionsUIBuilder` object in your `module.ts` file. Configure the editor to use by setting the `editor` property to the `SimpleEditor` component.
**module.ts**
```ts
export const plugin = new PanelPlugin<SimpleOptions>(SimplePanel).setPanelOptions((builder) => {
return builder.addCustomEditor({
id: 'label',
path: 'label',
name: 'Label',
editor: SimpleEditor,
});
});
```
## Add settings to your panel option editor
If you're using your custom editor to configure multiple options, you might want to be able to customize it. Add settings to your editor by setting the second template variable of `StandardEditorProps` to an interface that contains the settings you want to be able to configure.
You can access the editor settings through the `item` prop. Here's an example of an editor that populates a drop-down with a range of numbers. The range is defined by the `from` and `to` properties in the `Settings` interface.
**SimpleEditor.tsx**
```ts
interface Settings {
from: number;
to: number;
}
export const SimpleEditor: React.FC<StandardEditorProps<number, Settings>> = ({ item, value, onChange }) => {
const options: Array<SelectableValue<number>> = [];
// Default values
const from = item.settings?.from ?? 1;
const to = item.settings?.to ?? 10;
for (let i = from; i <= to; i++) {
options.push({
label: i.toString(),
value: i,
});
}
return <Select options={options} value={value} onChange={(selectableValue) => onChange(selectableValue.value)} />;
};
```
You can now configure the editor for each option, by configuring the `settings` property in the call to `addCustomEditor`.
```ts
export const plugin = new PanelPlugin<SimpleOptions>(SimplePanel).setPanelOptions((builder) => {
return builder.addCustomEditor({
id: 'index',
path: 'index',
name: 'Index',
editor: SimpleEditor,
settings: {
from: 1,
to: 10,
},
});
});
```
## Use query results in your panel option editor
Option editors can access the results from the last query. This lets you update your editor dynamically, based on the data returned by the data source.
> **Note:** This feature was introduced in 7.0.3. Anyone using an older version of Grafana will see an error when using your plugin.
The editor context is available through the `context` prop. The data frames returned by the data source are available under `context.data`.
**SimpleEditor.tsx**
```ts
export const SimpleEditor: React.FC<StandardEditorProps<string>> = ({ item, value, onChange, context }) => {
const options: SelectableValue<string>[] = [];
if (context.data) {
const frames = context.data;
for (let i = 0; i < frames.length; i++) {
options.push({
label: frames[i].name,
value: frames[i].name,
});
}
}
return <Select options={options} value={value} onChange={(selectableValue) => onChange(selectableValue.value)} />;
};
```
Have you built a custom editor that you think would be useful to other plugin developers? Consider contributing it as a standard editor!

View File

@@ -1,182 +0,0 @@
---
title: Data frames
---
# Data frames
Grafana supports a variety of different data sources, each with its own data model. To make this possible, Grafana consolidates the query results from each of these data sources into one unified data structure called a _data frame_.
The data frame structure is a concept that's borrowed from data analysis tools like the [R programming language](https://www.r-project.org) and [Pandas](https://pandas.pydata.org/).
> Data frames are available in Grafana 7.0+, and replaced the Time series and Table structures with a more generic data structure that can support a wider range of data types.
This document gives an overview of the data frame structure, and of how data is handled within Grafana.
## The data frame
A data frame is a columnar-oriented table structure, which means it stores data by column and not by row. To understand what this means, lets look at the TypeScript definition used by Grafana:
```ts
interface DataFrame {
name?: string;
// reference to query that create the frame
refId?: string;
fields: []Field;
}
```
In essence, a data frame is a collection of _fields_, where each field corresponds to a column. Each field, in turn, consists of a collection of values, along with meta information, such as the data type of those values.
```ts
interface Field {
name: string;
// Prometheus like Labels / Tags
labels?: Record<string, string>;
// For example string, number, time (or more specific primitives in the backend)
type: FieldType;
// Array of values all of the same type
values: Vector<T>;
// Optional display data for the field (e.g. unit, name over-ride, etc)
config: FieldConfig;
}
```
Let's look at an example. The table below demonstrates a data frame with two fields, _time_ and _temperature_.
| time | temperature |
| ------------------- | ----------- |
| 2020-01-02 03:04:00 | 45.0 |
| 2020-01-02 03:05:00 | 47.0 |
| 2020-01-02 03:06:00 | 48.0 |
Each field has three values, and each value in a field must share the same type. In this case, all values in the time field are timestamps, and all values in the temperature field are numbers.
One restriction on data frames is that all fields in the frame must be of the same length to be a valid data frame.
### Field configuration
Each field in a data frame contains optional information about the values in the field, such as units, scaling, and so on.
By adding field configurations to a data frame, Grafana can configure visualizations automatically. For example, you could configure Grafana to automatically set the unit provided by the data source.
## Transformations
Along with the type information, field configs enable _data transformations_ within Grafana.
A data transformation is any function that accepts a data frame as input, and returns another data frame as output. By using data frames in your plugin, you get a range of transformations for free.
## Data frames as time series
A data frame with at least one time field is considered a _time series_.
For more information on time series, refer to our [Introduction to time series]({{< relref "../../fundamentals/timeseries/" >}}).
### Wide format
When a collection of time series shares the same _time index_—the time fields in each time series are identical—they can be stored together, in a _wide_ format. By reusing the time field, we can reduce the amount of data being sent to the browser.
In this example, the `cpu` usage from each host share the time index, so we can store them in the same data frame.
```text
Name: Wide
Dimensions: 3 fields by 2 rows
+---------------------+-----------------+-----------------+
| Name: time | Name: cpu | Name: cpu |
| Labels: | Labels: host=a | Labels: host=b |
| Type: []time.Time | Type: []float64 | Type: []float64 |
+---------------------+-----------------+-----------------+
| 2020-01-02 03:04:00 | 3 | 4 |
| 2020-01-02 03:05:00 | 6 | 7 |
+---------------------+-----------------+-----------------+
```
However, if the two time series don't share the same time values, they are represented as two distinct data frames.
```text
Name: cpu
Dimensions: 2 fields by 2 rows
+---------------------+-----------------+
| Name: time | Name: cpu |
| Labels: | Labels: host=a |
| Type: []time.Time | Type: []float64 |
+---------------------+-----------------+
| 2020-01-02 03:04:00 | 3 |
| 2020-01-02 03:05:00 | 6 |
+---------------------+-----------------+
Name: cpu
Dimensions: 2 fields by 2 rows
+---------------------+-----------------+
| Name: time | Name: cpu |
| Labels: | Labels: host=b |
| Type: []time.Time | Type: []float64 |
+---------------------+-----------------+
| 2020-01-02 03:04:01 | 4 |
| 2020-01-02 03:05:01 | 7 |
+---------------------+-----------------+
```
The wide format can typically be used when multiple time series are collected by the same process. In this case, every measurement is made at the same interval and will therefore share the same time values.
### Long format
Some data sources return data in a _long_ format (also called _narrow_ format). This is common format returned by, for example, SQL databases.
In long format, string values are represented as separate fields rather than as labels. As a result, a data form in long form may have duplicated time values.
Grafana can detect and convert data frames in long format into wide format.
> **Note:** Long format is currently only supported in the backend: [Grafana Issue #22219](https://github.com/grafana/grafana/issues/22219).
For example, the following data frame in long format:
```text
Name: Long
Dimensions: 4 fields by 4 rows
+---------------------+-----------------+-----------------+----------------+
| Name: time | Name: aMetric | Name: bMetric | Name: host |
| Labels: | Labels: | Labels: | Labels: |
| Type: []time.Time | Type: []float64 | Type: []float64 | Type: []string |
+---------------------+-----------------+-----------------+----------------+
| 2020-01-02 03:04:00 | 2 | 10 | foo |
| 2020-01-02 03:04:00 | 5 | 15 | bar |
| 2020-01-02 03:05:00 | 3 | 11 | foo |
| 2020-01-02 03:05:00 | 6 | 16 | bar |
+---------------------+-----------------+-----------------+----------------+
```
can be converted into a data frame in wide format:
```text
Name: Wide
Dimensions: 5 fields by 2 rows
+---------------------+------------------+------------------+------------------+------------------+
| Name: time | Name: aMetric | Name: bMetric | Name: aMetric | Name: bMetric |
| Labels: | Labels: host=foo | Labels: host=foo | Labels: host=bar | Labels: host=bar |
| Type: []time.Time | Type: []float64 | Type: []float64 | Type: []float64 | Type: []float64 |
+---------------------+------------------+------------------+------------------+------------------+
| 2020-01-02 03:04:00 | 2 | 10 | 5 | 15 |
| 2020-01-02 03:05:00 | 3 | 11 | 6 | 16 |
+---------------------+------------------+------------------+------------------+------------------+
```
> **Note:** Not all panels support the wide time series data frame format. To keep full backward compatibility we've introduced a transformation that can be used to convert from the wide to the long format. For usage information, refer to the [Prepare time series-transformation]({{< relref "../../panels-visualizations/query-transform-data/transform-data/#prepare-time-series" >}}).
## Technical references
This section contains links to technical reference and implementations of data frames.
### Apache Arrow
The data frame structure is inspired by, and uses the [Apache Arrow Project](https://arrow.apache.org/). Javascript Data frames use Arrow Tables as the underlying structure, and the backend Go code serializes its Frames in Arrow Tables for transmission.
### Javascript
The Javascript implementation of data frames is in the [`/src/dataframe` folder](https://github.com/grafana/grafana/tree/main/packages/grafana-data/src/dataframe) and [`/src/types/dataframe.ts`](https://github.com/grafana/grafana/blob/main/packages/grafana-data/src/types/dataFrame.ts) of the [`@grafana/data` package](https://github.com/grafana/grafana/tree/main/packages/grafana-data).
### Go
For documentation on the Go implementation of data frames, refer to the [github.com/grafana/grafana-plugin-sdk-go/data package](https://pkg.go.dev/github.com/grafana/grafana-plugin-sdk-go/data?tab=doc).

View File

@@ -1,170 +0,0 @@
---
title: Development with local Grafana
---
# Development with local Grafana
This guide allows you to setup a development environment where you run Grafana and your plugin locally. With this, you will be able to see your changes as you add them.
## Run Grafana in your host
If you have git, Go and the required version of NodeJS in your system, you can clone and run Grafana locally:
1. Download and set up Grafana. You can find instructions on how to do it in the [developer-guide](https://github.com/grafana/grafana/blob/HEAD/contribute/developer-guide.md).
2. Grafana will look for plugins, by default, on its `data/plugins` directory. You can create a symbolic link to your plugin repository to detect new changes:
```bash
ln -s <plugin-path>/dist data/plugins/<plugin-name>
```
3. (Optional) If the step above doesn't work for you (e.g. you are running on Windows), you can also modify the default path in the Grafana configuration (that can be found at `conf/custom.ini`) and point to the directory with your plugin:
```ini
[paths]
plugins = <path-to-your-plugin-parent-directory>
```
## Run Grafana with docker-compose
Another possibility is to run Grafana with docker-compose so it runs in a container. For doing so, create the docker-compose file in your plugin directory:
**NOTE**: Some plugins already include a docker-compose file so you can skip this step.
```yaml
version: '3.7'
services:
grafana:
# Change latest with your target version, if needed
image: grafana/grafana:latest
ports:
- 3000:3000/tcp
volumes:
# Use your plugin folder (e.g. redshift-datasource)
- ./dist:/var/lib/grafana/plugins/<plugin-folder>
- ./provisioning:/etc/grafana/provisioning
environment:
- TERM=linux
- GF_LOG_LEVEL=debug
- GF_DATAPROXY_LOGGING=true
- GF_DEFAULT_APP_MODE=development
```
## Run your plugin
Finally start your plugin in development mode. Go to your plugin root directory and follow these steps:
1. Build your plugin backend and start the frontend in watch mode:
```bash
mage -v
yarn watch
```
2. Start Grafana backend and frontend:
2.1 For a local copy of Grafana, go to the directory with Grafana source code and run:
```bash
make run
```
```bash
yarn start
```
2.2 Or with docker-compose, in your plugin directory, run:
```bash
docker-compose up
```
After this, you should be able to see your plugin listed in Grafana and test your changes. Note that any change in the fronted will require you to refresh your browser while changes in the backend may require to rebuild your plugin binaries and reload the plugin (`mage && mage reloadPlugin` for local development or `docker-compose up` again if you are using docker-compose).
## Run your backend plugin with a debugger
> Note: The following method only works with a local Grafana instance and currently doesn't work with Docker.
You can run a backend plugin and attach a debugger to it, which allows you to set breakpoints and debug your backend plugin directly from your IDE of choice.
We support Visual Studio Code and GoLand out of the box, but this feature can also work with any other IDE or debugger.
1. Go to your plugin's folder.
1. Check your `go.mod` and make sure `grafana-plugin-sdk-go` is at least on `v0.156.0`
- If not, update it to the latest version:
```
go get -u github.com/grafana/grafana-plugin-sdk-go
```
1. Build your plugin at least once:
```
yarn build && mage
```
1. Install your plugin into your local Grafana instance.
Now that your plugin is ready to run, follow the instructions bellow for your IDE of choice.
### Visual Studio Code
1. If it's not already present, go to your plugin's folder and place the following file inside `.vscode/launch.json`:
```json
{
"version": "0.2.0",
"configurations": [
{
"name": "Standalone debug mode",
"type": "go",
"request": "launch",
"mode": "debug",
"program": "${workspaceFolder}/pkg",
"env": {},
"args": ["-standalone"]
}
]
}
```
1. Press `F5` to run your plugin in debug mode.
1. Start Grafana, if it's not already running.
> If you re-run the configuration, Grafana will automatically reload the plugin.
### GoLand
1. Create a new Run/Debug configuration:
- **Run kind**: Package
- **Package path**: your `pkg` package
- **Program arguments**: `-standalone`
1. Run the config (with or without the debugger).
1. Start Grafana, if it's not already running.
> If you re-run the configuration, Grafana will automatically reload the plugin.
### Other IDEs
Configure your code editor to run the following steps:
1. Build the executable with debug flags.
```
mage build:debug
```
1. Run the plugin's executable (inside `dist`) with `-standalone -debug` flags.
```
./gpx_xyz_linux_amd64 -standalone -debug
```
1. Attach a debugger to the process.
Then, you can start Grafana, if it's not already running.
> If you re-run the configuration, Grafana will automatically reload the plugin.
### Notes
- All logs are printed in the plugin's `stdout` rather than in Grafana logs.
- If the backend plugin doesn't serve requests after turning off debug mode, you can force reset the standalone mode. To do so, delete the files `dist/standalone.txt` and `dist/pid.txt` alongside the executable file, and then restart Grafana.
- We currently do not support debugging backend plugins running inside Docker.

View File

@@ -1,63 +0,0 @@
---
title: Error handling
---
# Error handling
This guide explains how to handle errors in plugins.
## Provide usable defaults
Allow the user to learn your plugin in small steps. Provide a useful default configuration so that:
- The user can get started right away.
- You can avoid unnecessary error messages.
For example, by selecting the first field of an expected type, the panel can display a visualization without any user configuration. If a user explicitly selects a field, then use that one. Otherwise, default to the first field of type `string`:
```ts
const numberField = frame.fields.find((field) =>
options.numberFieldName ? field.name === options.numberFieldName : field.type === FieldType.number
);
```
## Display error messages
To display an error message to the user, `throw` an `Error` with the message you want to display:
```ts
throw new Error('An error occurred');
```
Grafana displays the error message in the top-left corner of the panel.
{{< figure src="/static/img/docs/panel_error.png" class="docs-image--no-shadow" max-width="850px" >}}
Avoid displaying overly-technical error messages to the user. If you want to let technical users report an error, consider logging it instead.
```ts
try {
failingFunction();
} catch (err) {
console.error(err);
throw new Error('Something went wrong');
}
```
> **Note:** Grafana displays the exception message in the UI as written, so we recommend using grammatically correct sentences. For more information, refer to the [Documentation style guide](https://github.com/grafana/grafana/blob/main/contribute/style-guides/documentation-style-guide.md).
Here are some examples of situations where you might want to display an error to the user.
### Invalid query response
Users have full freedom when they create data source queries for panels. If your panel plugin requires a specific format for the query response, then use the panel canvas to guide the user.
```ts
if (!numberField) {
throw new Error('Query result is missing a number field');
}
if (frame.length === 0) {
throw new Error('Query returned an empty result');
}
```

View File

@@ -1,12 +0,0 @@
---
description: Get started guide
title: Get started with plugins
---
# Get started with Grafana plugins
This section contains guidance for building plugins.
- [Get started with creating a plugin](https://grafana.github.io/plugin-tools/docs/getting-started)
- [Types of Grafana plugins](https://grafana.com/docs/grafana/latest/administration/plugin-management/)
- [Set up your development environment](https://grafana.github.io/plugin-tools/docs/docker)

View File

@@ -1,13 +0,0 @@
---
description: Conceptual topics for plugin development
title: Introduction to plugin development
---
# Introduction to Grafana plugin development
This section contains topics related to the key concepts for Grafana plugin development.
- [Backend plugins]({{< relref "../backend/" >}})
- [Grafana plugin SDK for Go]({{< relref "../backend/grafana-plugin-sdk-for-go.md" >}})
- [Plugin protocol]({{< relref "../backend/plugin-protocol.md" >}})
- [Data frames]({{< relref "data-frames.md">}})

View File

@@ -1,132 +0,0 @@
---
aliases:
- ../../plugins/development/
- /docs/grafana/next/plugins/apps/
- /docs/grafana/next/plugins/datasources/
- /docs/grafana/next/plugins/developing/development/
- /docs/grafana/next/plugins/panels/
title: Legacy plugins
---
# Legacy plugins
> **Note:** Since Grafana 7.0, writing plugins using Angular is no longer recommended. If you're looking to build a new plugin, refer to [Plugins]({{< relref "../" >}}).
You can extend Grafana by writing your own plugins and then share them with other users in [our plugin repository](https://grafana.com/plugins).
Grafana already has a strong community of contributors and plugin developers. By making it easier to develop and install plugins with resources such as this guide, we hope that the community can grow even stronger and develop new plugins that we would never think about.
## Short version
1. [Set up Grafana](https://github.com/grafana/grafana/blob/main/contribute/developer-guide.md)
1. Clone an example plugin into `/var/lib/grafana/plugins` or `data/plugins` (relative to grafana git repo if you're running development version from source dir)
1. Use one of our example plugins as a starting point
Example plugins
- ["Hello World" panel using Angular](https://github.com/grafana/simple-angular-panel)
- ["Hello World" panel using React](https://github.com/grafana/simple-react-panel)
- [Simple json data source](https://github.com/grafana/simple-json-datasource)
- [Clock panel](https://github.com/grafana/clock-panel)
- [Pie chart panel](https://github.com/grafana/piechart-panel)
You might also be interested in the available tutorials around authoring a plugin.
- [Grafana Tutorials](https://grafana.com/tutorials/)
## What languages?
Since everything turns into JavaScript, it's up to you to choose which language you want. That said, it's probably a good idea to choose es6 or TypeScript, because we use es6 classes in Grafana. So it's easier to get inspiration from the Grafana repo if you choose one of those languages.
## Buildscript
You can use any build system that supports systemjs. All the built content should end up in a folder named `dist` and be committed to the repository. By committing the dist folder, the person who installs your plugin does not have to run any build script. All of our example plugins have a build script configured.
## Keep your plugin up to date
New versions of Grafana can sometimes cause plugins to break. See our [documentation](https://grafana.com/docs/grafana/latest/developers/plugins/migration-guide/) for changes in
Grafana that can impact your plugin.
## Metadata
See the [coding styleguide]({{< relref "style-guide/" >}}) for details on the metadata.
## module.(js|ts)
This is the entry point for every plugin. This is the place where you should export
your plugin implementation. Depending on what kind of plugin you are developing you
will be expected to export different things. You can find what's expected for [datasource]({{< relref "data-sources/" >}}), [panels]({{< relref "panels/" >}})
and [apps]({{< relref "apps/" >}}) plugins in the documentation.
The Grafana SDK is quite small so far and can be found here:
- [SDK file in Grafana](https://github.com/grafana/grafana/blob/main/public/app/plugins/sdk.ts)
The SDK contains three different plugin classes: PanelCtrl, MetricsPanelCtrl and QueryCtrl. For plugins of the panel type, the module.js file should export one of these. There are some extra classes for [data sources]({{< relref "data-sources/" >}}).
Example:
```javascript
import { ClockCtrl } from './clock_ctrl';
export { ClockCtrl as PanelCtrl };
```
The module class is also where css for the dark and light themes is imported:
```javascript
import { loadPluginCss } from 'app/plugins/sdk';
import WorldmapCtrl from './worldmap_ctrl';
loadPluginCss({
dark: 'plugins/grafana-worldmap-panel/css/worldmap.dark.css',
light: 'plugins/grafana-worldmap-panel/css/worldmap.light.css',
});
export { WorldmapCtrl as PanelCtrl };
```
## Start developing your plugin
There are three ways that you can start developing a Grafana plugin.
1. Set up a Grafana development environment. [(described here)](https://github.com/grafana/grafana/blob/main/contribute/developer-guide.md) and place your plugin in the `data/plugins` folder.
1. Install Grafana and place your plugin in the plugins directory which is set in your [config file](/administration/configuration). By default this is `/var/lib/grafana/plugins` on Linux systems.
1. Place your plugin directory anywhere you like and specify it grafana.ini.
We encourage people to set up the full Grafana environment so that you can get inspiration from the rest of the Grafana code base.
When Grafana starts, it scans the plugin folders and mounts every folder that contains a plugin.json file unless
the folder contains a subfolder named dist. In that case, Grafana mounts the dist folder instead.
This makes it possible to have both built and src content in the same plugin Git repo.
## Grafana Events
There are a number of Grafana events that a plugin can hook into:
- `init-edit-mode` can be used to add tabs when editing a panel
- `panel-teardown` can be used for clean up
- `data-received` is an event in that is triggered on data refresh and can be hooked into
- `data-snapshot-load` is an event triggered to load data when in snapshot mode.
- `data-error` is used to handle errors on dashboard refresh.
If a panel receives data and hooks into the `data-received` event then it should handle snapshot mode too. Otherwise the panel will not work if saved as a snapshot. [Getting Plugins to work in Snapshot Mode]({{< relref "snapshot-mode/" >}}) describes how to add support for this.
## Examples
We have three different examples that you can fork/download to get started developing your Grafana plugin.
- [simple-json-datasource](https://github.com/grafana/simple-json-datasource) (small data source plugin for querying json data from backends)
- [simple-app-plugin](https://github.com/grafana/simple-app-plugin)
- [clock-panel](https://github.com/grafana/clock-panel)
- [singlestat-panel](https://github.com/grafana/grafana/tree/main/public/app/plugins/panel/singlestat)
- [piechart-panel](https://github.com/grafana/piechart-panel)
## Other Articles
- [Getting Plugins to work in Snapshot Mode]({{< relref "snapshot-mode/" >}})
- [Plugin Defaults and Editor Mode]({{< relref "defaults-and-editor-mode/" >}})
- [Grafana Plugin Code Styleguide]({{< relref "style-guide/" >}})
- [Grafana Apps]({{< relref "apps/" >}})
- [Grafana Data Sources]({{< relref "data-sources/" >}})
- [plugin.json Schema]({{< relref "../metadata/" >}})

View File

@@ -1,56 +0,0 @@
---
aliases:
- ../../../plugins/developing/apps/
keywords:
- grafana
- plugins
- documentation
title: Legacy app plugins
---
# Legacy app plugins
App plugins are Grafana plugins that can bundle data source and panel plugins within one package. They also enable the plugin author to create custom pages within Grafana. The custom pages enable the plugin author to include things like documentation, sign-up forms, or to control other services with HTTP requests.
Data source and panel plugins will show up like normal plugins. The app pages will be available in the main menu.
## Enabling app plugins
After installing an app, it has to be enabled before it shows up as a data source or panel. You can do that on the app page in the configuration tab.
## Developing an App Plugin
An App is a bundle of panels, dashboards and/or data source(s). There is nothing different about developing panels and data sources for an app.
Apps have to be enabled in Grafana and should import any included dashboards when the user enables it. A ConfigCtrl class should be created and the dashboards imported in the postUpdate hook. See example below:
```javascript
export class ConfigCtrl {
/** @ngInject */
constructor($scope, $injector, $q) {
this.$q = $q;
this.enabled = false;
this.appEditCtrl.setPostUpdateHook(this.postUpdate.bind(this));
}
postUpdate() {
if (!this.appModel.enabled) {
return;
}
// TODO, whatever you want
console.log('Post Update:', this);
}
}
ConfigCtrl.templateUrl = 'components/config/config.html';
```
If possible, a link to a dashboard or custom page should be shown after enabling the app to guide the user to the appropriate place.
{{< figure class="float-right" src="/static/img/docs/app_plugin_after_enable.png" caption="After enabling" >}}
### Develop your own App
> Our goal is not to have a very extensive documentation but rather have actual
> code that people can look at. An example implementation of an app can be found
> in this [example app repo](https://github.com/grafana/simple-app-plugin)

View File

@@ -1,184 +0,0 @@
---
aliases:
- ../../../plugins/developing/datasources/
keywords:
- grafana
- plugins
- documentation
title: Legacy data source plugins
---
# Legacy data source plugins
Data source plugins enable people to develop plugins for any database that
communicates over HTTP. Its up to the plugin to transform the data into
time series data so that any grafana panel can then show it.
## Data source development
> Our goal is not to have a very extensive documentation but rather have actual
> code that people can look at. Example implementations of a data source can be
> found in these repos:
> - [simple-json-datasource](https://github.com/grafana/simple-json-datasource)
> - [simple-datasource](https://github.com/grafana/simple-datasource)
> - [simple-json-backend-datasource](https://github.com/grafana/simple-json-backend-datasource)
To interact with the rest of grafana the plugins module file can export 4 different components.
- Datasource (Required)
- QueryCtrl (Required)
- ConfigCtrl (Required)
- AnnotationsQueryCtrl
## Plugin json
There are two data source specific settings for the plugin.json
```json
"metrics": true,
"annotations": false,
```
These settings indicate what kind of data the plugin can deliver. At least one of them has to be true.
## Data source
The javascript object that communicates with the database and transforms data to times series.
The Data source should contain the following functions:
```javascript
query(options); // used by panels to get data
testDatasource(); // used by data source configuration page to make sure the connection is working
annotationQuery(options); // used by dashboards to get annotations
metricFindQuery(options); // used by query editor to get metric suggestions.
```
### testDatasource
When a user clicks on the _Save & Test_ button when adding a new data source, the details are first saved to the database and then the `testDatasource` function that is defined in your data source plugin will be called. It is recommended that this function makes a query to the data source that will also test that the authentication details are correct. This is so the data source is correctly configured when the user tries to write a query in a new dashboard.
### Query
Request object passed to datasource.query function:
```json
{
"range": { "from": "2015-12-22T03:06:13.851Z", "to": "2015-12-22T06:48:24.137Z" },
"interval": "5s",
"targets": [
{ "refId": "B", "target": "upper_75" },
{ "refId": "A", "target": "upper_90" }
],
"format": "json",
"maxDataPoints": 2495 // decided by the panel
}
```
There are two different kinds of results for data sources:
time series and table. Time series is the most common format and is supported by all data sources and panels. Table format is only supported by the InfluxDB data source and table panel. But we might see more of this in the future.
Time series response from datasource.query.
An array of:
```json
[
{
"target": "upper_75",
"datapoints": [
[622, 1450754160000],
[365, 1450754220000]
]
},
{
"target": "upper_90",
"datapoints": [
[861, 1450754160000],
[767, 1450754220000]
]
}
]
```
Table response from datasource.query.
An array of:
```json
[
{
"columns": [
{
"text": "Time",
"type": "time",
"sort": true,
"desc": true
},
{
"text": "mean"
},
{
"text": "sum"
}
],
"rows": [
[1457425380000, null, null],
[1457425370000, 1002.76215352, 1002.76215352]
],
"type": "table"
}
]
```
### Annotation Query
Request object passed to datasource.annotationQuery function:
```json
{
"range": { "from": "2016-03-04T04:07:55.144Z", "to": "2016-03-04T07:07:55.144Z" },
"rangeRaw": { "from": "now-3h", "to": "now" },
"annotation": {
"datasource": "generic datasource",
"enable": true,
"name": "annotation name"
},
"dashboard": DashboardModel
}
```
Expected result from datasource.annotationQuery:
```json
[
{
"annotation": {
"name": "annotation name", //should match the annotation name in grafana
"enabled": true,
"datasource": "generic datasource"
},
"title": "Cluster outage",
"time": 1457075272576,
"text": "Joe causes brain split",
"tags": ["joe", "cluster", "failure"]
}
]
```
## QueryCtrl
A JavaScript class that will be instantiated and treated as an Angular controller when the user edits metrics in a panel. This class has to inherit from the `app/plugins/sdk.QueryCtrl` class.
Requires a static template or `templateUrl` variable which will be rendered as the view for this controller.
## ConfigCtrl
A JavaScript class that will be instantiated and treated as an Angular controller when a user tries to edit or create a new data source of this type.
Requires a static template or `templateUrl` variable which will be rendered as the view for this controller.
## AnnotationsQueryCtrl
A JavaScript class that will be instantiated and treated as an Angular controller when the user chooses this type of data source in the templating menu in the dashboard.
Requires a static template or `templateUrl` variable which will be rendered as the view for this controller. The fields that are bound to this controller are then sent to the Database objects annotationQuery function.

View File

@@ -1,136 +0,0 @@
---
aliases:
- ../../../plugins/developing/defaults-and-editor-mode/
title: Legacy defaults and editor mode
---
# Legacy defaults and editor mode
Most plugins allow users to customize the behavior by changing settings on an editor tab. These setting fields are saved in the dashboard json.
## Defaults
We define fields to be saved in Grafana by creating values on the panel object of the controller. You can see these values for any panel by choosing View JSON from the settings menu in Grafana. Here is an excerpt from the clock panel json (with some fields removed), the panel data is saved in the panels array:
```json
{
"id": 4,
"title": "Clock",
...
"rows": [
{
...
"panels": [
{
"bgColor": "rgb(132, 151, 130)",
"clockType": "24 hour",
```
You can define panel data by first creating a variable with default values for the fields and then setting them on the panel object:
```javascript
const panelDefaults = {
clockType: '24 hour',
fontSize: '60px',
fontWeight: 'normal',
bgColor: null
};
constructor($scope, $injector) {
super($scope, $injector);
_.defaults(this.panel, panelDefaults);
this.updateClock();
}
```
The Lodash function [defaults](https://lodash.com/docs/4.17.4#defaults), which is called in the code above: `_.defaults`, sets a default value only if the value is not already set. This way values that have been changed by the user will not be overwritten.
These panel fields can be used in the controller or module.html template:
```html
<h2 style="font-size: {{ctrl.panel.fontSize}};">{{ctrl.time}}</h2>
```
If you want your users to be able to change these panel values then you need to expose them in the Grafana editor.
## Editor Mode
Editor mode is when a user clicks Edit on a panel. Every panel has a general tab where you change the title and width and some panels have more inbuilt tabs like the Metrics tab or Time Range tab. A panel plugin can add its own tab(s) so that a user can customize the panel.
Grafana conventions mean all you need to do is to hook up an Angular template with input fields and Grafana will automatically save the values to the dashboard json and load them on dashboard load.
## Using Events
To add an editor tab you need to hook into the event model so that the tab is added when the _init-edit-mode_ event is triggered. The following code should be added to the constructor of the plugin Ctrl class:
```javascript
this.events.on('init-edit-mode', this.onInitEditMode.bind(this));
```
Then you need to create a handler function that is bound to the event. In the example above, the handler is called onInitEditMode. The tab is added by calling the controller function, _addEditorTab_. This function has three parameters; the tab name, the path to a html template for the new editor tab and the tab number. It can be a bit tricky to figure out the path, the path name will be based on the id that is specified in the plugin.json file - for example **grafana-clock-panel**. The code below hooks up an Angular template called editor.html that is located in the `src/partials` directory.
```javascript
onInitEditMode() {
this.addEditorTab('Options', 'public/plugins/grafana-clock-panel/editor.html', 2);
}
```
## Editor HTML and CSS
For editor tabs html, it is best to use Grafana css styles rather than custom styles. This is to preserve the look and feel of other tabs in Grafana.
Most editor tabs should use the [gf-form css class](https://github.com/grafana/grafana/blob/main/public/sass/components/_gf-form.scss) from Grafana. The example below has one row with a couple of columns and each column is wrapped in a div like this:
```html
<div class="section gf-form-group"></div>
```
Then each pair, label and field is wrapped in a div with a gf-form class.
```html
<div class="gf-form">
<label class="gf-form-label width-8">Font Size</label>
<input
type="text"
class="gf-form-input width-4"
ng-model="ctrl.panel.fontSize"
ng-change="ctrl.render()"
ng-model-onblur
/>
</div>
```
Note that there are some Angular attributes here. _ng-model_ will update the panel data. _ng-change_ will render the panel when you change the value. This change will occur on the onblur event due to the _ng-model-onblur_ attribute. This means you can see the effect of your changes on the panel while editing.
{{< figure class="float-right" src="/assets/img/blog/clock-panel-editor.png" caption="Panel Editor" >}}
On the editor tab we use a drop-down for 12/24 hour clock, an input field for font size and a color picker for the background color.
The drop-down/select has its own _gf-form-select-wrapper_ css class and looks like this:
```html
<div class="gf-form">
<label class="gf-form-label width-9">12 or 24 hour</label>
<div class="gf-form-select-wrapper max-width-9">
<select
class="input-small gf-form-input"
ng-model="ctrl.panel.clockType"
ng-options="t for t in ['12 hour', '24 hour', 'custom']"
ng-change="ctrl.render()"
></select>
</div>
</div>
```
The color picker (or spectrum picker) is a component that already exists in Grafana. We use it like this for the background color:
```html
<spectrum-picker class="gf-form-input" ng-model="ctrl.panel.bgColor" ng-change="ctrl.render()"></spectrum-picker>
```
## Editor Tab Finished
To reiterate, this all ties together quite neatly. We specify properties and panel defaults in the constructor for the panel controller and these can then be changed in the editor. Grafana takes care of saving the changes.
One thing to be aware of is that panel defaults are used the first time a panel is created to set the initial values of the panel properties. After the panel is saved then the saved value will be used instead. So beware if you update panel defaults they will not automatically update the property in an existing panel. For example, if you set the default font size to 60px first and then in version 2 of the plugin change it to 50px, existing panels will still have 60px and only new panels will get the new 50px value.

View File

@@ -1,33 +0,0 @@
---
aliases:
- ../../../plugins/developing/panels/
keywords:
- grafana
- plugins
- panel
- documentation
title: Legacy panel plugins
---
# Legacy panel plugins
Panels are the main building blocks of dashboards.
## Panel development
### Scrolling
The grafana dashboard framework controls the panel height. To enable a scrollbar within the panel the PanelCtrl needs to set the scrollable static variable:
```javascript
export class MyPanelCtrl extends PanelCtrl {
static scrollable = true;
...
```
In this case, make sure the template has a single `<div>...</div>` root. The plugin loader will modify that element adding a scrollbar.
### Examples
- [clock-panel](https://github.com/grafana/clock-panel)
- [singlestat-panel](https://github.com/grafana/grafana/tree/main/public/app/plugins/panel/singlestat)

View File

@@ -1,181 +0,0 @@
---
aliases:
- ../../../plugins/developing/plugin-review-guidelines/
title: Legacy review guidelines
---
# Legacy review guidelines
The Grafana team reviews all plugins that are published on Grafana.com. There are two areas we review, the metadata for the plugin and the plugin functionality.
## Metadata
The plugin metadata consists of a `plugin.json` file and the README.md file. The `plugin.json` file is used by Grafana to load the plugin, and the README.md file is shown in the plugins section of Grafana and the plugins section of https://grafana.com.
### README.md
The README.md file is shown on the plugins page in Grafana and the plugin page on Grafana.com. There are some differences between the GitHub markdown and the markdown allowed in Grafana/Grafana.com:
- Cannot contain inline HTML.
- Any image links should be absolute links. For example: https://raw.githubusercontent.com/grafana/azure-monitor-datasource/master/dist/img/grafana_cloud_install.png
The README should:
- describe the purpose of the plugin.
- contain steps on how to get started.
### Plugin.json
The `plugin.json` file is the same concept as the `package.json` file for an npm package. When the Grafana server starts it will scan the plugin folders (all folders in the data/plugins subfolder) and load every folder that contains a `plugin.json` file unless the folder contains a subfolder named `dist`. In that case, the Grafana server will load the `dist` folder instead.
A minimal `plugin.json` file:
```json
{
"type": "panel",
"name": "Clock",
"id": "yourorg-clock-panel",
"info": {
"description": "Clock panel for grafana",
"author": {
"name": "Author Name",
"url": "http://yourwebsite.com"
},
"keywords": ["clock", "panel"],
"version": "1.0.0",
"updated": "2018-03-24"
},
"dependencies": {
"grafanaVersion": "3.x.x",
"plugins": []
}
}
```
- The convention for the plugin id is **[grafana.com username/org]-[plugin name]-[datasource|app|panel]** and it has to be unique. The org **cannot** be `grafana` unless it is a plugin created by the Grafana core team.
Examples:
- raintank-worldping-app
- ryantxu-ajax-panel
- alexanderzobnin-zabbix-app
- hawkular-datasource
- The `type` field should be either `datasource` `app` or `panel`.
- The `version` field should be in the form: x.x.x e.g. `1.0.0` or `0.4.1`.
The full file format for `plugin.json` file is in [plugin.json](http://docs.grafana.org/plugins/developing/plugin.json/).
## Plugin Language
JavaScript, TypeScript, ES6 (or any other language) are all fine as long as the contents of the `dist` subdirectory are transpiled to JavaScript (ES5).
## File and Directory Structure Conventions
Here is a typical directory structure for a plugin.
```bash
johnnyb-awesome-datasource
|-- dist
|-- src
| |-- img
| | |-- logo.svg
| |-- partials
| | |-- annotations.editor.html
| | |-- config.html
| | |-- query.editor.html
| |-- datasource.js
| |-- module.js
| |-- plugin.json
| |-- query_ctrl.js
|-- Gruntfile.js
|-- LICENSE
|-- package.json
|-- README.md
```
Most JavaScript projects have a build step. The generated JavaScript should be placed in the `dist` directory and the source code in the `src` directory. We recommend that the plugin.json file be placed in the src directory and then copied over to the dist directory when building. The `README.md` can be placed in the root or in the dist directory.
Directories:
- `src/` contains plugin source files.
- `src/partials` contains html templates.
- `src/img` contains plugin logos and other images.
- `dist/` contains built content.
## HTML and CSS
For the HTML on editor tabs, we recommend using the inbuilt Grafana styles rather than defining your own. This makes plugins feel like a more natural part of Grafana. If done correctly, the html will also be responsive and adapt to smaller screens. The `gf-form` css classes should be used for labels and inputs.
Below is a minimal example of an editor row with one form group and two fields, a dropdown and a text input:
```html
<div class="editor-row">
<div class="section gf-form-group">
<h5 class="section-heading">My Plugin Options</h5>
<div class="gf-form">
<label class="gf-form-label width-10">Label1</label>
<div class="gf-form-select-wrapper max-width-10">
<select
class="input-small gf-form-input"
ng-model="ctrl.panel.mySelectProperty"
ng-options="t for t in ['option1', 'option2', 'option3']"
ng-change="ctrl.onSelectChange()"
></select>
</div>
<div class="gf-form">
<label class="gf-form-label width-10">Label2</label>
<input
type="text"
class="input-small gf-form-input width-10"
ng-model="ctrl.panel.myProperty"
ng-change="ctrl.onFieldChange()"
placeholder="suggestion for user"
ng-model-onblur
/>
</div>
</div>
</div>
</div>
```
Use the `width-x` and `max-width-x` classes to control the width of your labels and input fields. Try to get labels and input fields to line up neatly by having the same width for all the labels in a group and the same width for all inputs in a group if possible.
## Data Sources
For more information about data sources, refer to the [basic guide for data sources](http://docs.grafana.org/plugins/developing/datasources/).
### Configuration Page Guidelines
- It should be as easy as possible for a user to configure a URL. If the data source is using the `datasource-http-settings` component, it should use the `suggest-url` attribute to suggest the default URL or a URL that is similar to what it should be (especially important if the URL refers to a REST endpoint that is not common knowledge for most users e.g. `https://yourserver:4000/api/custom-endpoint`).
```html
<datasource-http-settings current="ctrl.current" suggest-url="http://localhost:8080"> </datasource-http-settings>
```
- The `testDatasource` function should make a query to the data source that will also test that the authentication details are correct. This is so the data source is correctly configured when the user tries to write a query in a new dashboard.
#### Password Security
If possible, any passwords or secrets should be saved in the `secureJsonData` blob. To encrypt sensitive data, the Grafana server's proxy feature must be used. The Grafana server has support for token authentication (OAuth) and HTTP Header authentication. If the calls have to be sent directly from the browser to a third-party API, this will not be possible and sensitive data will not be encrypted.
Read more here about how [authentication for data sources]({{< relref "../add-authentication-for-data-source-plugins/" >}}) works.
If using the proxy feature, the Configuration page should use the `secureJsonData` blob like this:
- good: `<input type="password" class="gf-form-input" ng-model='ctrl.current.secureJsonData.password' placeholder="password"></input>`
- bad: `<input type="password" class="gf-form-input" ng-model='ctrl.current.password' placeholder="password"></input>`
### Query Editor
Each query editor is unique and can have a unique style. It should be adapted to what the users of the data source are used to.
- Should use the Grafana CSS `gf-form` classes.
- Should be neat and tidy. Labels and fields in columns should be aligned and should be the same width if possible.
- The data source should be able to handle when a user toggles a query (by clicking on the eye icon) and not execute the query. This is done by checking the `hide` property - an [example](https://github.com/grafana/grafana/blob/e75840737e81f70b6d169df21eca86a624d4bdc4/public/app/plugins/datasource/postgres/datasource.ts#L73).
- Should not execute queries if fields in the Query Editor are empty and the query will throw an exception (defensive programming).
- Should handle errors. There are two main ways to do this:
- use the notification system in Grafana to show a toaster pop-up with the error message. For an example of a pop-up with the error message, refer to [code in triggers_panel_ctrl](https://github.com/alexanderzobnin/grafana-zabbix/blob/fdbbba2fb03f5f2a4b3b0715415e09d5a4cf6cde/src/panel-triggers/triggers_panel_ctrl.js#L467-L471).
- provide an error notification in the query editor like the MySQL/Postgres data sources do. For an example of error notification in the query editor, refer to [code in query_ctrl](https://github.com/grafana/azure-monitor-datasource/blob/b184d077f082a69f962120ef0d1f8296a0d46f03/src/query_ctrl.ts#L36-L51) and in the [html](https://github.com/grafana/azure-monitor-datasource/blob/b184d077f082a69f962120ef0d1f8296a0d46f03/src/partials/query.editor.html#L190-L193).

View File

@@ -1,76 +0,0 @@
---
aliases:
- ../../../plugins/developing/snapshot-mode/
title: Legacy snapshot mode
---
# Legacy snapshot mode
{{< figure class="float-right" src="/static/img/docs/Grafana-snapshot-example.png" caption="A dashboard using snapshot data and not live data." >}}
Grafana has this great feature where you can [save a snapshot of your dashboard]({{< relref "../../../dashboards/build-dashboards/view-dashboard-json-model" >}}). Instead of sending a screenshot of a dashboard to someone, you can send them a working, interactive Grafana dashboard with the snapshot data embedded inside it. The snapshot can be saved on your Grafana server and is available to all your co-workers. Raintank also hosts a [snapshot server](https://snapshots.raintank.io) if you want to send the snapshot to someone who does not have access to your Grafana server.
{{< figure class="float-right" src="/static/img/docs/animated_gifs/snapshots.gif" caption="Selecting a snapshot" >}}
This all works because Grafana saves a snapshot of the current data in the dashboard json instead of fetching the data from a data source. However, if you are building a custom panel plugin then this will not work straight out of the box. You will need to make some small (and easy!) changes first.
## Enabling support for loading snapshot data
Grafana automatically saves data from data sources in the dashboard json when the snapshot is created so we do not have to write any code for that. Enabling snapshot support for reading time series data is very simple. First in the constructor, we need to add an event handler for `data-snapshot-load`. This event is triggered by Grafana when the snapshot data is loaded from the dashboard json.
```javascript
constructor($scope, $injector, contextSrv) {
super($scope, $injector);
...
this.events.on('init-edit-mode', this.onInitEditMode.bind(this));
this.events.on('data-received', this.onDataReceived.bind(this));
this.events.on('panel-teardown', this.onPanelTeardown.bind(this));
this.events.on('data-snapshot-load', this.onDataSnapshotLoad.bind(this));
```
Then we need to create a simple event handler that just forwards the data on to our regular `data-received` handler:
```javascript
onDataSnapshotLoad(snapshotData) {
this.onDataReceived(snapshotData);
}
```
This will cover most use cases for snapshot support. Sometimes you will want to save data that is not time series data from a Grafana data source and then you have to do a bit more work to get snapshot support.
## Saving custom data for snapshots
Data that is not time series data from a Grafana data source is not saved automatically by Grafana. Saving custom data for snapshot mode has to be done manually.
{{< figure class="float-right" src="/static/img/docs/Grafana-save-snapshot.png" caption="Save snapshot" >}}
Grafana gives us a chance to save data to the dashboard json when it is creating a snapshot. In the 'data-received' event handler, you can check the snapshot flag on the dashboard object. If this is true, then Grafana is creating a snapshot and you can manually save custom data to the panel json. In the example, a new field called snapshotLocationData in the panel json is initialized with a snapshot of the custom data.
```javascript
onDataReceived(dataList) {
if (!dataList) return;
if (this.dashboard.snapshot && this.locations) {
this.panel.snapshotLocationData = this.locations;
}
```
Now the location data is saved in the dashboard json but we will have to load it manually as well.
## Loading custom data for snapshots
The example below shows a function that loads the custom data. The data source for the custom data (an external API in this case) is not available in snapshot mode so a guard check is made to see if there is any snapshot data available first. If there is, then the snapshot data is used instead of trying to load the data from the external API.
```javascript
loadLocationDataFromFile(reload) {
if (this.map && !reload) return;
if (this.panel.snapshotLocationData) {
this.locations = this.panel.snapshotLocationData;
return;
}
```
It is really easy to forget to add this support but it enables a great feature and can be used to demo your panel.
If there is a panel plugin that you would like to be installed on the Raintank Snapshot server then please contact us via [Slack](https://slack.grafana.com) or [GitHub](https://github.com/grafana/grafana).

View File

@@ -1,193 +0,0 @@
---
aliases:
- ../../../plugins/developing/code-styleguide/
title: Legacy code style guide
---
# Legacy code style guide
This guide has two parts. The first part describes the metadata and the second part is a styleguide for HTML/CSS and JavaScript in Grafana plugins and applies if you are using ES6 in your plugin. If using TypeScript then the [Angular TypeScript styleguide](https://angular.io/styleguide) is recommended.
## Metadata
The plugin metadata consists of a plugin.json file and the README.md file. These two files are used by Grafana and Grafana.com.
### Plugin.json (mandatory)
The plugin.json file is the same concept as the package.json file for an npm package. When Grafana starts it will scan the plugin folders and mount every folder that contains a plugin.json file unless the folder contains a subfolder named `dist`. In that case grafana will mount the `dist` folder instead.
The most important fields are the first three, especially the id. The convention for the plugin id is **[github username/org]-[plugin name]-[datasource|app|panel]** and it has to be unique.
Examples:
```bash
raintank-worldping-app
grafana-simple-json-datasource
grafana-piechart-panel
mtanda-histogram-panel
```
For more information about the file format for `plugin.json` file, refer to [metadata]({{< relref "../metadata/" >}}).
Minimal plugin.json:
```javascript
{
"type": "panel",
"name": "Clock",
"id": "yourorg-clock-panel",
"info": {
"description": "Clock panel for grafana",
"author": {
"name": "Grafana Labs",
"url": "https://grafana.com"
},
"keywords": ["clock", "panel"],
"version": "1.0.0",
"updated": "2015-03-24"
},
"dependencies": {
"grafanaVersion": "3.x.x",
"plugins": [ ]
}
}
```
### README.md
The README.md file is rendered both in the grafana.com plugins page, and within the Grafana application. The only difference from how GitHub renders markdown is that html is not allowed.
## File and Directory Structure Conventions
Here is a typical directory structure for a plugin.
```bash
johnnyb-awesome-datasource
|-- dist
|-- spec
| |-- datasource_spec.js
| |-- query_ctrl_spec.js
| |-- test-main.js
|-- src
| |-- img
| | |-- logo.svg
| |-- partials
| | |-- annotations.editor.html
| | |-- config.html
| | |-- query.editor.html
| |-- datasource.js
| |-- module.js
| |-- plugin.json
| |-- query_ctrl.js
|-- Gruntfile.js
|-- LICENSE
|-- package.json
|-- README.md
```
Most JavaScript projects have a build step and most Grafana plugins are built using Babel and ES6. The generated JavaScript should be placed in the `dist` directory and the source code in the `src` directory. We recommend that the plugin.json file be placed in the src directory and then copied over to the dist directory when building. The `README.md` can be placed in the root or in the dist directory.
Directories:
- `src/` contains plugin source files.
- `src/partials` contains html templates.
- `src/img` contains plugin logos and other images.
- `spec/` contains tests (optional).
- `dist/` contains built content.
## HTML and CSS
For the HTML on editor tabs, we recommend using the inbuilt Grafana styles rather than defining your own. This makes plugins feel like a more natural part of Grafana. If done correctly, the html will also be responsive and adapt to smaller screens. The `gf-form` css classes should be used for labels and inputs.
Below is a minimal example of an editor row with one form group and two fields, a dropdown and a text input:
```html
<div class="editor-row">
<div class="section gf-form-group">
<h5 class="section-heading">My Plugin Options</h5>
<div class="gf-form">
<label class="gf-form-label width-10">Label1</label>
<div class="gf-form-select-wrapper max-width-10">
<select
class="input-small gf-form-input"
ng-model="ctrl.panel.mySelectProperty"
ng-options="t for t in ['option1', 'option2', 'option3']"
ng-change="ctrl.onSelectChange()"
></select>
</div>
<div class="gf-form">
<label class="gf-form-label width-10">Label2</label>
<input
type="text"
class="input-small gf-form-input width-10"
ng-model="ctrl.panel.myProperty"
ng-change="ctrl.onFieldChange()"
placeholder="suggestion for user"
ng-model-onblur
/>
</div>
</div>
</div>
</div>
```
Use the `width-x` and `max-width-x` classes to control the width of your labels and input fields. Try to get labels and input fields to line up neatly by having the same width for all the labels in a group and the same width for all inputs in a group if possible.
## Build Scripts
Our recommendation is to use whatever you usually use - Grunt, Gulp or npm scripts. Most plugins seems to use Grunt so that is probably the easiest to get started with if you do not have a preferred build system. The only requirement is that it supports systemjs which is required by Grafana to load plugins.
## Linting
We recommend that you use a linter for your JavaScript. For ES6, the standard linter is [eslint](http://eslint.org/). Rules for linting are described in an .eslintrc that is placed in the root directory. For an example of linting rules in a plugin, refer to [.eslintrc](https://github.com/grafana/worldmap-panel/blob/master/.eslintrc).
### ES6 features
1. Use `const` if a variable is not going to be reassigned.
1. Prefer to use `let` instead `var` ([Exploring ES6](http://exploringjs.com/es6/ch_core-features.html#_from-var-to-letconst))
1. Use arrow functions, which dont shadow `this` ([Exploring ES6](http://exploringjs.com/es6/ch_core-features.html#_from-function-expressions-to-arrow-functions)):
```js
testDatasource() {
return this.getServerStatus()
.then(status => {
return this.doSomething(status);
})
}
```
better than
```js
testDatasource() {
var self = this;
return this.getServerStatus()
.then(function(status) {
return self.doSomething(status);
})
}
```
1. Use native _Promise_ object:
```js
metricFindQuery(query) {
if (!query) {
return Promise.resolve([]);
}
}
```
better than
```js
metricFindQuery(query) {
if (!query) {
return this.$q.when([]);
}
}
```
1. If using Lodash, then be consistent and prefer that to the native ES6 array functions.

View File

@@ -1,254 +0,0 @@
---
aliases:
- ../../plugins/developing/plugin.json/
keywords:
- grafana
- plugins
- documentation
title: plugin.json
---
# plugin.json
The plugin.json file is required for all plugins. When Grafana starts, it scans the plugin folders and mounts every folder that contains a plugin.json file unless the folder contains a subfolder named dist. In that case, Grafana mounts the dist folder instead.
## Properties
| Property | Type | Required | Description |
| -------------------- | ----------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `dependencies` | [object](#dependencies) | **Yes** | Dependencies needed by the plugin. |
| `id` | string | **Yes** | Unique name of the plugin. If the plugin is published on grafana.com, then the plugin id has to follow the naming conventions. |
| `info` | [object](#info) | **Yes** | Metadata for the plugin. Some fields are used on the plugins page in Grafana and others on grafana.com if the plugin is published. |
| `name` | string | **Yes** | Human-readable name of the plugin that is shown to the user in the UI. |
| `type` | string | **Yes** | Plugin type. Possible values are: `app`, `datasource`, `panel`. |
| `$schema` | string | No | Schema definition for the plugin.json file. |
| `alerting` | boolean | No | For data source plugins, if the plugin supports alerting. |
| `annotations` | boolean | No | For data source plugins, if the plugin supports annotation queries. |
| `autoEnabled` | boolean | No | Set to true for app plugins that should be enabled by default in all orgs |
| `backend` | boolean | No | If the plugin has a backend component. |
| `category` | string | No | Plugin category used on the Add data source page. Possible values are: `tsdb`, `logging`, `cloud`, `tracing`, `sql`, `enterprise`, `other`. |
| `enterpriseFeatures` | [object](#enterprisefeatures) | No | Grafana Enerprise specific features. |
| `executable` | string | No | The first part of the file name of the backend component executable. There can be multiple executables built for different operating system and architecture. Grafana will check for executables named `<executable>_<$GOOS>_<lower case $GOARCH><.exe for Windows>`, e.g. `plugin_linux_amd64`. Combination of $GOOS and $GOARCH can be found here: https://golang.org/doc/install/source#environment. |
| `hiddenQueries` | boolean | No | For data source plugins, include hidden queries in the data request. |
| `includes` | [object](#includes)[] | No | Resources to include in plugin. |
| `logs` | boolean | No | For data source plugins, if the plugin supports logs. |
| `metrics` | boolean | No | For data source plugins, if the plugin supports metric queries. Used in Explore. |
| `preload` | boolean | No | Initialize plugin on startup. By default, the plugin initializes on first use. |
| `queryOptions` | [object](#queryoptions) | No | For data source plugins. There is a query options section in the plugin's query editor and these options can be turned on if needed. |
| `routes` | [object](#routes)[] | No | For data source plugins. Proxy routes used for plugin authentication and adding headers to HTTP requests made by the plugin. For more information, refer to [Authentication for data source plugins](https://grafana.com/docs/grafana/latest/developers/plugins/authentication/). |
| `skipDataQuery` | boolean | No | For panel plugins. Hides the query editor. |
| `state` | string | No | Marks a plugin as a pre-release. Possible values are: `alpha`, `beta`. |
| `streaming` | boolean | No | For data source plugins, if the plugin supports streaming. |
| `tables` | boolean | No | This is an undocumented feature. |
| `tracing` | boolean | No | For data source plugins, if the plugin supports tracing. |
## dependencies
Dependencies needed by the plugin.
### Properties
| Property | Type | Required | Description |
| ------------------- | -------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `grafanaDependency` | string | **Yes** | Required Grafana version for this plugin. Validated using https://github.com/npm/node-semver. |
| `grafanaVersion` | string | No | (Deprecated) Required Grafana version for this plugin, e.g. `6.x.x 7.x.x` to denote plugin requires Grafana v6.x.x or v7.x.x. |
| `plugins` | [object](#plugins)[] | No | An array of required plugins on which this plugin depends. |
### plugins
Plugin dependency. Used to display information about plugin dependencies in the Grafana UI.
#### Properties
| Property | Type | Required | Description |
| --------- | ------ | -------- | -------------------------------------------------- |
| `id` | string | **Yes** | |
| `name` | string | **Yes** | |
| `type` | string | **Yes** | Possible values are: `app`, `datasource`, `panel`. |
| `version` | string | **Yes** | |
## enterpriseFeatures
Grafana Enerprise specific features.
### Properties
| Property | Type | Required | Description |
| ------------------------- | ------- | -------- | ------------------------------------------------------------------- |
| `healthDiagnosticsErrors` | boolean | No | Enable/Disable health diagnostics errors. Requires Grafana >=7.5.5. |
## includes
### Properties
| Property | Type | Required | Description |
| ------------ | ------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `addToNav` | boolean | No | Add the include to the side menu. |
| `component` | string | No | (Legacy) The Angular component to use for a page. |
| `defaultNav` | boolean | No | Page or dashboard when user clicks the icon in the side menu. |
| `icon` | string | No | Icon to use in the side menu. For information on available icon, refer to [Icons Overview](https://developers.grafana.com/ui/latest/index.html?path=/story/docs-overview-icon--icons-overview). |
| `name` | string | No | |
| `path` | string | No | Used for app plugins. |
| `role` | string | No | Possible values are: `Admin`, `Editor`, `Viewer`. |
| `type` | string | No | Possible values are: `dashboard`, `page`, `panel`, `datasource`. |
| `uid` | string | No | Unique identifier of the included resource |
## info
Metadata for the plugin. Some fields are used on the plugins page in Grafana and others on grafana.com if the plugin is published.
### Properties
| Property | Type | Required | Description |
| ------------- | ------------------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `keywords` | string[] | **Yes** | Array of plugin keywords. Used for search on grafana.com. |
| `logos` | [object](#logos) | **Yes** | SVG images that are used as plugin icons. |
| `updated` | string | **Yes** | Date when this plugin was built. |
| `version` | string | **Yes** | Project version of this commit, e.g. `6.7.x`. |
| `author` | [object](#author) | No | Information about the plugin author. |
| `build` | [object](#build) | No | Build information |
| `description` | string | No | Description of plugin. Used on the plugins page in Grafana and for search on grafana.com. |
| `links` | [object](#links)[] | No | An array of link objects to be displayed on this plugin's project page in the form `{name: 'foo', url: 'http://example.com'}` |
| `screenshots` | [object](#screenshots)[] | No | An array of screenshot objects in the form `{name: 'bar', path: 'img/screenshot.png'}` |
### author
Information about the plugin author.
#### Properties
| Property | Type | Required | Description |
| -------- | ------ | -------- | ------------------------- |
| `email` | string | No | Author's name. |
| `name` | string | No | Author's name. |
| `url` | string | No | Link to author's website. |
### build
Build information
#### Properties
| Property | Type | Required | Description |
| -------- | ------ | -------- | ---------------------------------------------------- |
| `branch` | string | No | Git branch the plugin was built from. |
| `hash` | string | No | Git hash of the commit the plugin was built from |
| `number` | number | No | |
| `pr` | number | No | GitHub pull request the plugin was built from |
| `repo` | string | No | |
| `time` | number | No | Time when the plugin was built, as a Unix timestamp. |
### links
#### Properties
| Property | Type | Required | Description |
| -------- | ------ | -------- | ----------- |
| `name` | string | No | |
| `url` | string | No | |
### logos
SVG images that are used as plugin icons.
#### Properties
| Property | Type | Required | Description |
| -------- | ------ | -------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `large` | string | **Yes** | Link to the "large" version of the plugin logo, which must be an SVG image. "Large" and "small" logos can be the same image. |
| `small` | string | **Yes** | Link to the "small" version of the plugin logo, which must be an SVG image. "Large" and "small" logos can be the same image. |
### screenshots
#### Properties
| Property | Type | Required | Description |
| -------- | ------ | -------- | ----------- |
| `name` | string | No | |
| `path` | string | No | |
## queryOptions
For data source plugins. There is a query options section in the plugin's query editor and these options can be turned on if needed.
### Properties
| Property | Type | Required | Description |
| --------------- | ------- | -------- | -------------------------------------------------------------------------------------------------------------------------- |
| `cacheTimeout` | boolean | No | For data source plugins. If the `cache timeout` option should be shown in the query options section in the query editor. |
| `maxDataPoints` | boolean | No | For data source plugins. If the `max data points` option should be shown in the query options section in the query editor. |
| `minInterval` | boolean | No | For data source plugins. If the `min interval` option should be shown in the query options section in the query editor. |
## routes
For data source plugins. Proxy routes used for plugin authentication and adding headers to HTTP requests made by the plugin. For more information, refer to [Authentication for data source plugins](https://grafana.com/docs/grafana/latest/developers/plugins/authentication/).
### Properties
| Property | Type | Required | Description |
| -------------- | ----------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `body` | [object](#body) | No | For data source plugins. Route headers set the body content and length to the proxied request. |
| `headers` | array | No | For data source plugins. Route headers adds HTTP headers to the proxied request. |
| `jwtTokenAuth` | [object](#jwttokenauth) | No | For data source plugins. Token authentication section used with an JWT OAuth API. |
| `method` | string | No | For data source plugins. Route method matches the HTTP verb like GET or POST. Multiple methods can be provided as a comma-separated list. |
| `path` | string | No | For data source plugins. The route path that is replaced by the route URL field when proxying the call. |
| `reqRole` | string | No | |
| `reqSignedIn` | boolean | No | |
| `tokenAuth` | [object](#tokenauth) | No | For data source plugins. Token authentication section used with an OAuth API. |
| `url` | string | No | For data source plugins. Route URL is where the request is proxied to. |
### body
For data source plugins. Route headers set the body content and length to the proxied request.
| Property | Type | Required | Description |
| -------- | ---- | -------- | ----------- |
### jwtTokenAuth
For data source plugins. Token authentication section used with an JWT OAuth API.
#### Properties
| Property | Type | Required | Description |
| -------- | ----------------- | -------- | --------------------------------------------------------------------- |
| `params` | [object](#params) | No | Parameters for the JWT token authentication request. |
| `scopes` | string[] | No | The list of scopes that your application should be granted access to. |
| `url` | string | No | URL to fetch the JWT token. |
#### params
Parameters for the JWT token authentication request.
##### Properties
| Property | Type | Required | Description |
| -------------- | ------ | -------- | ----------- |
| `client_email` | string | No | |
| `private_key` | string | No | |
| `token_uri` | string | No | |
### tokenAuth
For data source plugins. Token authentication section used with an OAuth API.
#### Properties
| Property | Type | Required | Description |
| -------- | ----------------- | -------- | --------------------------------------------------------------------- |
| `params` | [object](#params) | No | Parameters for the token authentication request. |
| `scopes` | string[] | No | The list of scopes that your application should be granted access to. |
| `url` | string | No | URL to fetch the authentication token. |
#### params
Parameters for the token authentication request.
##### Properties
| Property | Type | Required | Description |
| --------------- | ------ | -------- | ----------------------------------------------------------------------------------------- |
| `client_id` | string | No | OAuth client ID |
| `client_secret` | string | No | OAuth client secret. Usually populated by decrypting the secret from the SecureJson blob. |
| `grant_type` | string | No | OAuth grant type |
| `resource` | string | No | OAuth resource |

View File

@@ -1,10 +0,0 @@
+++
# -------------------------------------------------------------------------
# Do not edit this file. It is automatically generated by json-schema-docs.
# -------------------------------------------------------------------------
title = "plugin.json"
keywords = ["grafana", "plugins", "documentation"]
aliases = ["/docs/grafana/latest/plugins/developing/plugin.json/"]
+++
{{ .Markdown 1 }}

View File

@@ -1,954 +0,0 @@
---
title: Plugin migration guide
---
# Plugin migration guide
## Introduction
This guide helps you identify the steps required to update a plugin from the Grafana version it currently supports to newer versions of Grafana.
> **Note:** If you've successfully migrated your plugin using this guide, then share your experiences with us! If you find missing information, then we encourage you to [submit an issue on GitHub](https://github.com/grafana/grafana/issues/new?title=Docs%20feedback:%20/developers/plugins/migration-guide.md) so that we can improve this guide!
## Table of contents
- [Plugin migration guide](#plugin-migration-guide)
- [Introduction](#introduction)
- [Table of contents](#table-of-contents)
- [From version 9.3.x to 9.4.x](#from-version-93x-to-94x)
- [Supporting new navigation layout](#supporting-new-navigation-layout)
- [Forwarded HTTP headers in grafana-plugin-sdk-go](#forwarded-http-headers-in-grafana-plugin-sdk-go)
- [From version 9.1.x to 9.2.x](#from-version-91x-to-92x)
- [React and React-dom as peer dependencies](#react-and-react-dom-as-peer-dependencies)
- [NavModelItem requires a valid icon name](#navmodelitem-requires-a-valid-icon-name)
- [Additional type availability](#additional-type-availability)
- [From version 8.x to 9.x](#from-version-8x-to-9x)
- [9.0 breaking changes](#90-breaking-changes)
- [theme.visualization.getColorByName replaces getColorForTheme](#themevisualizationgetcolorbyname-replaces-getcolorfortheme)
- [VizTextDisplayOptions replaces TextDisplayOptions](#viztextdisplayoptions-replaces-textdisplayoptions)
- [Changes in the internal of `backendSrv.fetch()`](#changes-in-the-internal-of-backendsrvfetch)
- [GrafanaTheme2 and useStyles2 replaces getFormStyles](#grafanatheme2-and-usestyles2-replaces-getformstyles)
- [/api/ds/query replaces /api/tsdb/query](#apidsquery-replaces-apitsdbquery)
- [selectOptionInTest has been removed](#selectoptionintest-has-been-removed)
- [Toolkit 9 and webpack](#toolkit-9-and-webpack)
- [From version 8.3.x to 8.4.x](#from-version-83x-to-84x)
- [Value Mapping Editor has been removed from @grafana-ui library](#value-mapping-editor-has-been-removed-from-grafana-ui-library)
- [Thresholds Editor has been removed from @grafana-ui library](#thresholds-editor-has-been-removed-from-grafana-ui-library)
- [8.4 deprecations](#84-deprecations)
- [LocationService replaces getLocationSrv](#locationservice-replaces-getlocationsrv)
- [From version 7.x.x to 8.x.x](#from-version-7xx-to-8xx)
- [Backend plugin v1 support has been dropped](#backend-plugin-v1-support-has-been-dropped)
- [1. Add dependency on grafana-plugin-sdk-go](#1-add-dependency-on-grafana-plugin-sdk-go)
- [2. Update the way you bootstrap your plugin](#2-update-the-way-you-bootstrap-your-plugin)
- [3. Update the plugin package](#3-update-the-plugin-package)
- [Sign and load backend plugins](#sign-and-load-backend-plugins)
- [Update react-hook-form from v6 to v7](#update-react-hook-form-from-v6-to-v7)
- [Update the plugin.json](#update-the-pluginjson)
- [Update imports to match emotion 11](#update-imports-to-match-emotion-11)
- [Update needed for app plugins using dashboards](#update-needed-for-app-plugins-using-dashboards)
- [8.0 deprecations](#80-deprecations)
- [Grafana theme v1](#grafana-theme-v1)
- [From version 6.2.x to 7.4.0](#from-version-62x-to-740)
- [Legend components](#legend-components)
- [From version 6.5.x to 7.3.0](#from-version-65x-to-730)
- [getColorForTheme changes](#getcolorfortheme-changes)
- [From version 6.x.x to 7.0.0](#from-version-6xx-to-700)
- [What's new in Grafana 7.0?](#whats-new-in-grafana-70)
- [New data format](#new-data-format)
- [Improved TypeScript support](#improved-typescript-support)
- [Grafana Toolkit](#grafana-toolkit)
- [Field options](#field-options)
- [Backend plugins](#backend-plugins)
- [Migrate a plugin from Angular to React](#migrate-a-plugin-from-angular-to-react)
- [Migrate a panel plugin](#migrate-a-panel-plugin)
- [Migrate a data source plugin](#migrate-a-data-source-plugin)
- [Migrate to data frames](#migrate-to-data-frames)
- [Troubleshoot plugin migration](#troubleshoot-plugin-migration)
## From version 9.3.x to 9.4.x
### Supporting new navigation layout
First, enable the `topnav` feature flag in `custom.ini` to check how your plugin renders in the new navigation layout:
```ini
[feature_toggles]
enable = topnav
```
#### Migrate from `onNavChanged`
If your plugin uses the `onNavChanged` callback to inform Grafana of its nav model & sub pages, you should see that this results in duplicated navigation elements. If you disable `topnav` it should look just as before.
When `topnav` is enabled we need to update the plugin to take advantage of the new `PluginPage` component and not call `onNavChanged`. `onNavChanged` is now deprecated.
#### Switch to `PluginPage` component
Grafana now exposes a new `PluginPage` component from `@grafana/runtime` that hooks into the new navigation and page layouts and supports the old page layouts when the `topnav` feature is disabled. This new component will also handle rendering the section navigation. The section navigation can include other core sections and other plugins. To control what pages are displayed in the section navigation for a specific plugin, Grafana will use the pages added in `plugin.json` that have `addToNav` set to `true`.
This component is very easy to use. Simply wrap it around your page content:
```tsx
import { PluginPage } from '@grafana/runtime';
...
return (
<PluginPage>
{your page content here}
</PluginPage>
);
```
Grafana will look at the URL to know what plugin and page should be active in the section nav, so this only works for pages you have specified in `plugin.json`. `PluginPage` will then render a page header based on the page name specified in `plugin.json`.
#### Using `PluginPage` for pages not defined in `plugin.json`
The `PluginPage` component also exposes a `pageNav` property that is a `NavModelItem`. This `pageNav` property is useful for pages that are not defined in `plugin.json` (e.g. individual item pages). The `text` and `description` you specify in the `pageNav` model will be used to populate the breadcrumbs and page header.
Example:
```tsx
const pageNav = {
text: 'Write errors cortex-prod-04',
description: 'Incident timeline and details'
};
return (
<PluginPage pageNav={pageNav}>
{your page content here}
</PluginPage>
);
```
The way the active page is matched in the breadcrumbs and section nav relies on the page routes being hierarchical. If you have a list page and an item page, the item page needs to be a subroute of the list page and the list page url needs to be specified in your `plugin.json`. For example, you might have a list of users at `/users`. This means that the item page for a specific user needs to be at `/users/:id`. This may require some refactoring of your routes.
#### Using `PluginPage` with tabs
You can also create a further layer of hierarchy by specifying `children` in the `pageNav` model to created a page with tabbed navigation.
Example:
```tsx
const pageNav = {
text: 'My page',
description: 'Incident timeline and details',
url: '/a/myorgid-pluginname-app',
children: [
{
url: '/a/myorgid-pluginname-app/tab1',
text: 'Tab1',
active: true,
},
{
url: '/a/myorgid-pluginname-app/tab2',
text: 'Tab1',
},
],
};
return (
<PluginPage pageNav={pageNav}>
{your page content here}
</PluginPage>
);
```
#### Using `PluginPage` in a backwards-compatible way
If you want to maintain backwards-compatibility with older versions of Grafana, one way is to implement a `PluginPage` wrapper. If `PluginPage` is available and the `topnav` feature is enabled then use the real `PluginPage`, otherwise fallback to whatever each plugin is doing today (including calling `onNavChanged`).
Example:
```tsx
import { PluginPageProps, PluginPage as RealPluginPage, config } from '@grafana/runtime';
export const PluginPage = RealPluginPage && config.featureToggles.topnav ? RealPluginPage : PluginPageFallback;
function PluginPageFallback(props: PluginPageProps) {
return props.children;
}
```
Theres an additional step (and if block) needed to hide/show tabs depending on if `config.features.topnav` is `true`. These changes will need to be made in the `useNavModel.ts` file in your plugin:
```tsx
// useNavModel.ts
import { config } from '@grafana/runtime';
...
export function useNavModel({ meta, rootPath, onNavChanged }: Args) {
const { pathname, search } = useLocation();
useEffect(() => {
if (config.featureToggles.topnav) {
return;
}
}, [config]);
...
```
### Forwarded HTTP headers in grafana-plugin-sdk-go
It's recommended to use the `<request>.GetHTTPHeader` or `<request>.GetHTTPHeaders` methods when retrieving forwarded HTTP headers. See [Forward OAuth identity for the logged-in user]({{< relref "add-authentication-for-data-source-plugins.md#forward-oauth-identity-for-the-logged-in-user" >}}), [Forward cookies for the logged-in user
]({{< relref "add-authentication-for-data-source-plugins.md#forward-cookies-for-the-logged-in-user" >}}) or [Forward user header for the logged-in user]({{< relref "add-authentication-for-data-source-plugins.md#forward-user-header-for-the-logged-in-user" >}}) for example usages.
#### Technical details
The grafana-plugin-sdk-go [v0.147.0](https://github.com/grafana/grafana-plugin-sdk-go/releases/tag/v0.147.0) introduces a new interface [ForwardHTTPHeaders](https://pkg.go.dev/github.com/grafana/grafana-plugin-sdk-go@v0.147.0/backend#ForwardHTTPHeaders) that `QueryDataRequest`, `CheckHealthRequest` and `CallResourceRequest` implements.
Newly introduced forwarded HTTP headers in Grafana v9.4.0 are `X-Grafana-User`, `X-Panel-Id`, `X-Dashboard-Uid`, `X-Datasource-Uid` and `X-Grafana-Org-Id`. Internally these are prefixed with `http_` and sent as `http_<HTTP header name>` in [CheckHealthRequest.Headers](https://pkg.go.dev/github.com/grafana/grafana-plugin-sdk-go@v0.147.0/backend#CheckHealthRequest) and [QueryDataRequest.Headers](https://pkg.go.dev/github.com/grafana/grafana-plugin-sdk-go@v0.147.0/backend#QueryDataRequest). By using the [ForwardHTTPHeaders](https://pkg.go.dev/github.com/grafana/grafana-plugin-sdk-go@v0.147.0/backend#ForwardHTTPHeaders) methods you're guaranteed to be able to operate on HTTP headers without using the prefix, i.e. `X-Grafana-User`, `X-Panel-Id`, `X-Dashboard-Uid`, `X-Datasource-Uid` and `X-Grafana-Org-Id`.
## From version 9.1.x to 9.2.x
### React and React-dom as peer dependencies
In earlier versions of Grafana packages `react` and `react-dom` were installed during a `yarn install` regardless of a plugins dependencies. In 9.2.0 the `@grafana` packages declare these react packages as peerDependencies and will need adding to a plugins `package.json` file for test commands to continue to run successfully.
Example:
```json
// before
"dependencies": {
"@grafana/data": "9.1.0",
"@grafana/ui": "9.1.0",
},
// after
"dependencies": {
"@grafana/data": "9.2.0",
"@grafana/ui": "9.2.0",
"react": "17.0.2",
"react-dom": "17.0.2"
},
```
### NavModelItem requires a valid icon name
The typings of the `NavModelItem` have improved to only allow a valid `IconName` for the icon property. You can find the complete list of valid icons [here](https://github.com/grafana/grafana/blob/v9.2.0-beta1/packages/grafana-data/src/types/icon.ts). The icons specified in the list will work for older versions of Grafana 9.
Example:
```ts
// before
const model: NavModelItem = {
id: 'settings',
text: 'Settings',
icon: 'fa fa-cog',
url: `${baseUrl}/settings`,
};
// after
const model: NavModelItem = {
id: 'settings',
text: 'Settings',
icon: 'cog',
url: `${baseUrl}/settings`,
};
```
### Additional type availability
FieldProps, ModalProps, and QueryFieldProps are now exposed from `@grafana/ui`. They can be imported in the same way as other types.
Example:
```ts
import { FieldProps, ModalProps, QueryFieldProps } from '@grafana/ui';
```
## From version 8.x to 9.x
### 9.0 breaking changes
#### theme.visualization.getColorByName replaces getColorForTheme
`getColorForTheme` was removed, use `theme.visualization.getColorByName` instead
Example:
```ts
// before
fillColor: getColorForTheme(panel.sparkline.fillColor, config.theme)
// after
fillColor: config.theme.visualization.getColorByName(panel.sparkline.fillColor),
```
#### VizTextDisplayOptions replaces TextDisplayOptions
`TextDisplayOptions` was removed, use `VizTextDisplayOptions` instead
Example:
```ts
// before
interface Options {
...
text?: TextDisplayOptions;
...
}
// after
interface Options {
...
text?: VizTextDisplayOptions;
...
}
```
#### Changes in the internal of `backendSrv.fetch()`
We have changed the internals of `backendSrv.fetch()` to throw an error when the response is an incorrect JSON. Make sure to handle possible errors on the callsite where using `backendSrv.fetch()` (or any other `backendSrv` methods)
```ts
// PREVIOUSLY: this was returning with an empty object {} - in case the response is an invalid JSON
return await getBackendSrv().post(`${API_ROOT}/${id}/install`);
// AFTER THIS CHANGE: the following will throw an error - in case the response is an invalid JSON
return await getBackendSrv().post(`${API_ROOT}/${id}/install`);
```
#### GrafanaTheme2 and useStyles2 replaces getFormStyles
We have removed the deprecated `getFormStyles` function from [grafana-ui](https://www.npmjs.com/package/@grafana/ui). Use `GrafanaTheme2` and the `useStyles2` hook instead
#### /api/ds/query replaces /api/tsdb/query
We have removed the deprecated `/api/tsdb/query` metrics endpoint. Use [/api/ds/query]({{< relref "../http_api/data_source/#query-a-data-source" >}}) instead
#### selectOptionInTest has been removed
The `@grafana/ui` package helper function `selectOptionInTest` used in frontend tests has been removed as it caused testing libraries to be bundled in the production code of Grafana. If you were using this helper function in your tests please update your code accordingly:
```ts
// before
import { selectOptionInTest } from '@grafana/ui';
// ...test usage
await selectOptionInTest(selectEl, 'Option 2');
// after
import { select } from 'react-select-event';
// ...test usage
await select(selectEl, 'Option 2', { container: document.body });
```
#### Toolkit 9 and webpack
Plugins using custom Webpack configs could potentially break due to the changes between webpack@4 and webpack@5. Please refer to the [official migration guide](https://webpack.js.org/migrate/5/) for assistance.
Webpack 5 does not include polyfills for node.js core modules by default (e.g. `buffer`, `stream`, `os`). This can result in failed builds for plugins. If polyfills are required it is recommended to create a custom webpack config in the root of the plugin repo and add the required fallbacks:
```js
// webpack.config.js
module.exports.getWebpackConfig = (config, options) => ({
...config,
resolve: {
...config.resolve,
fallback: {
os: require.resolve('os-browserify/browser'),
stream: require.resolve('stream-browserify'),
timers: require.resolve('timers-browserify'),
},
},
});
```
Please refer to the webpack build error messages or the [official migration guide](https://webpack.js.org/migrate/5/) for assistance with fallbacks.
## From version 8.3.x to 8.4.x
This section explains how to migrate Grafana v8.3.x plugins to the updated plugin system available in Grafana v8.4.x. Depending on your plugin, you need to perform one or more of the following steps.
### Value Mapping Editor has been removed from @grafana-ui library
Removed due to being an internal component.
### Thresholds Editor has been removed from @grafana-ui library
Removed due to being an internal component.
### 8.4 deprecations
#### LocationService replaces getLocationSrv
In a previous release, we migrated to use a new routing system and introduced a new service for managing locations, navigation, and related information. In this release, we are making that new service the primary service.
**Example:** Import the service.
```ts
// before
import { getLocationSrv } from '@grafana/runtime';
// after
import { locationService } from '@grafana/runtime';
```
**Example:** Navigate to a path and add a new record in the navigation history so that you can navigate back to the previous one.
```ts
// before
getLocationSrv.update({
path: '/route-to-navigate-to',
replace: false,
});
// after
locationService.push('/route-to-navigate-to');
```
**Example:** Navigate to a path and replace the current record in the navigation history.
```ts
// before
getLocationSrv.update({
path: '/route-to-navigate-to',
replace: true,
});
// after
locationService.replace('/route-to-navigate-to');
```
**Example:** Update the search or query parameter for the current route and add a new record in the navigation history so that you can navigate back to the previous one.
```ts
// How to navigate to a new path
// before
getLocationSrv.update({
query: {
value: 1,
},
partial: true,
replace: false,
});
// after
locationService.partial({ value: 1 });
```
**Example:** Update the search or query parameter for the current route and add replacing it in the navigation history.
```ts
// before
getLocationSrv.update({
query: {
'var-variable': 1,
},
partial: true,
replace: true,
});
// after
locationService.partial({ 'var-variable': 1 }, true);
```
## From version 7.x.x to 8.x.x
This section explains how to migrate Grafana v7.x.x plugins to the updated plugin system available in Grafana v8.x.x. Depending on your plugin, you need to perform one or more of the following steps. We have documented the breaking changes in Grafana v8.x.x and the steps you need to take to upgrade your plugin.
### Backend plugin v1 support has been dropped
Use the new [plugin sdk](https://github.com/grafana/grafana-plugin-sdk-go) to run your backend plugin running in Grafana 8.
#### 1. Add dependency on grafana-plugin-sdk-go
Add a dependency on the `https://github.com/grafana/grafana-plugin-sdk-go`. We recommend using [go modules](https://go.dev/blog/using-go-modules) to manage your dependencies.
#### 2. Update the way you bootstrap your plugin
Update your `main` package to bootstrap via the new plugin sdk.
```go
// before
package main
import (
"github.com/grafana/grafana_plugin_model/go/datasource"
hclog "github.com/hashicorp/go-hclog"
plugin "github.com/hashicorp/go-plugin"
"github.com/myorgid/datasource/pkg/plugin"
)
func main() {
pluginLogger.Debug("Running GRPC server")
ds, err := NewSampleDatasource(pluginLogger);
if err != nil {
pluginLogger.Error("Unable to create plugin");
}
plugin.Serve(&plugin.ServeConfig{
HandshakeConfig: plugin.HandshakeConfig{
ProtocolVersion: 1,
MagicCookieKey: "grafana_plugin_type",
MagicCookieValue: "datasource",
},
Plugins: map[string]plugin.Plugin{
"myorgid-datasource": &datasource.DatasourcePluginImpl{Plugin: ds},
},
GRPCServer: plugin.DefaultGRPCServer,
})
}
// after
package main
import (
"os"
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
"github.com/grafana/grafana-plugin-sdk-go/backend/datasource"
"github.com/myorgid/datasource/pkg/plugin"
)
func main() {
log.DefaultLogger.Debug("Running GRPC server")
if err := datasource.Manage("myorgid-datasource", NewSampleDatasource, datasource.ManageOpts{}); err != nil {
log.DefaultLogger.Error(err.Error())
os.Exit(1)
}
}
```
#### 3. Update the plugin package
Update your `plugin` package to use the new plugin sdk.
```go
// before
package plugin
import (
"context"
"github.com/grafana/grafana_plugin_model/go/datasource"
"github.com/hashicorp/go-hclog"
)
func NewSampleDatasource(pluginLogger hclog.Logger) (*SampleDatasource, error) {
return &SampleDatasource{
logger: pluginLogger,
}, nil
}
type SampleDatasource struct{
logger hclog.Logger
}
func (d *SampleDatasource) Query(ctx context.Context, tsdbReq *datasource.DatasourceRequest) (*datasource.DatasourceResponse, error) {
d.logger.Info("QueryData called", "request", req)
// logic for querying your datasource.
}
// after
package plugin
import (
"context"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt"
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
"github.com/grafana/grafana-plugin-sdk-go/data"
)
func NewSampleDatasource(_ backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) {
return &SampleDatasource{}, nil
}
type SampleDatasource struct{}
func (d *SampleDatasource) Dispose() {
// Clean up datasource instance resources.
}
func (d *SampleDatasource) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
log.DefaultLogger.Info("QueryData called", "request", req)
// logic for querying your datasource.
}
func (d *SampleDatasource) CheckHealth(_ context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) {
log.DefaultLogger.Info("CheckHealth called", "request", req)
// The main use case for these health checks is the test button on the
// datasource configuration page which allows users to verify that
// a datasource is working as expected.
}
```
### Sign and load backend plugins
We strongly recommend that you not allow unsigned plugins in your Grafana installation. By allowing unsigned plugins, we cannot guarantee the authenticity of the plugin, which could compromise the security of your Grafana installation.
To sign your plugin, see [Sign a plugin](https://grafana.com/docs/grafana/latest/developers/plugins/sign-a-plugin/#sign-a-plugin).
You can still run and develop an unsigned plugin by running your Grafana instance in [development mode](https://grafana.com/docs/grafana/latest/administration/configuration/#app_mode). Alternatively, you can use the [allow_loading_unsigned_plugins]({{< relref "../../setup-grafana/configure-grafana/#allow_loading_unsigned_plugins" >}}) configuration setting.
### Update react-hook-form from v6 to v7
We have upgraded react-hook-form from version 6 to version 7. To make your forms compatible with version 7, refer to the [react-hook-form-migration-guide](https://react-hook-form.com/migrate-v6-to-v7/).
### Update the plugin.json
The property that defines which Grafana version your plugin supports has been renamed and now it is a range instead of a specific version.
```json
// before
{
"dependencies": {
"grafanaVersion": "7.5.x",
"plugins": []
}
}
// after
{
"dependencies": {
"grafanaDependency": ">=8.0.0",
"plugins": []
}
}
```
### Update imports to match emotion 11
Grafana uses Emotion library to manage frontend styling. We have updated the Emotion package and this can affect your frontend plugin if you have custom styling. You only need to update the import statements to get it working in Grafana 8.
```ts
// before
import { cx, css } from 'emotion';
// after
import { cx, css } from '@emotion/css';
```
### Update needed for app plugins using dashboards
To make side navigation work properly - app plugins targeting Grafana `8.+` and integrating into the side menu via [addToNav]({{< relref "metadata/#properties-4" >}}) property need to adjust their `plugin.json` and all dashboard json files to have a matching `uid`.
**`plugin.json`**
```json "linenos=inline,hl_lines=7,linenostart=1"
{
"id": "plugin-id",
// ...
"includes": [
{
"type": "dashboard",
"name": "(Team) Situation Overview",
"path": "dashboards/example-dashboard.json",
"addToNav": true,
"defaultNav": false,
"uid": "l3KqBxCMz"
}
]
// ...
}
```
**`dashboards/example-dashboard.json`**
```json
{
// ...
"title": "Example Dashboard",
"uid": "l3KqBxCMz",
"version": 1
// ...
}
```
### 8.0 deprecations
#### Grafana theme v1
In Grafana 8 we have introduced a new improved version of our theming system. The previous version of the theming system is still available but is deprecated and will be removed in the next major version of Grafana.
You can find more detailed information on how to apply the v2 theme [here](https://github.com/grafana/grafana/blob/main/contribute/style-guides/themes.md#theming-grafana).
**How to style a functional component**
The `useStyles` hook is the preferred way to access the theme when styling. It provides basic memoization and access to the theme object.
```ts
// before
import React, { ReactElement } from 'react';
import css from 'emotion';
import { GrafanaTheme } from '@grafana/data';
import { useStyles } from '@grafana/ui';
function Component(): ReactElement | null {
const styles = useStyles(getStyles);
}
const getStyles = (theme: GrafanaTheme) => ({
myStyle: css`
background: ${theme.colors.bodyBg};
display: flex;
`,
});
// after
import React, { ReactElement } from 'react';
import { css } from '@emotion/css';
import { GrafanaTheme2 } from '@grafana/data';
import { useStyles2 } from '@grafana/ui';
function Component(): ReactElement | null {
const theme = useStyles2(getStyles);
}
const getStyles = (theme: GrafanaTheme2) => ({
myStyle: css`
background: ${theme.colors.background.canvas};
display: flex;
`,
});
```
**How to use the theme in a functional component**
```ts
// before
import React, { ReactElement } from 'react';
import { useTheme } from '@grafana/ui';
function Component(): ReactElement | null {
const theme = useTheme();
}
// after
import React, { ReactElement } from 'react';
import { useTheme2 } from '@grafana/ui';
function Component(): ReactElement | null {
const theme = useTheme2();
// Your component has access to the theme variables now
}
```
**How to use the theme in a class component**
```ts
// before
import React from 'react';
import { Themeable, withTheme } from '@grafana/ui';
type Props = {} & Themeable;
class Component extends React.Component<Props> {
render() {
const { theme } = this.props;
// Your component has access to the theme variables now
}
}
export default withTheme(Component);
// after
import React from 'react';
import { Themeable2, withTheme2 } from '@grafana/ui';
type Props = {} & Themeable2;
class Component extends React.Component<Props> {
render() {
const { theme } = this.props;
// Your component has access to the theme variables now
}
}
export default withTheme2(Component);
```
**Gradually migrating components**
If you need to use both the v1 and v2 themes due to using migrated and non-migrated components in the same context, use the `v1` property on the `v2` theme as described in the following example.
```ts
function Component(): ReactElement | null {
const theme = useTheme2();
return (
<NonMigrated theme={theme.v1}>
<Migrated theme={theme] />
</NonMigrate>
);
};
```
## From version 6.2.x to 7.4.0
### Legend components
The Legend components have been refactored and introduced the following changes within the `@grafana/ui` package.
```ts
// before
import { LegendItem, LegendOptions, GraphLegend } from '@grafana/ui';
// after
import { VizLegendItem, VizLegendOptions, VizLegend } from '@grafana/ui';
```
- `LegendPlacement` has been updated from `'under' | 'right' | 'over'` to `'bottom' | 'right'` so you can not place the legend above the visualization anymore.
- The `isVisible` in the `LegendItem` has been renamed to `disabled` in `VizLegendItem`.
## From version 6.5.x to 7.3.0
### getColorForTheme changes
The `getColorForTheme` function arguments have changed from `(color: ColorDefinition, theme?: GrafanaThemeType)` to `(color: string, theme: GrafanaTheme)`.
```ts
// before
const color: ColorDefinition = {
hue: 'green';
name: 'dark-green';
variants: {
light: '#19730E'
dark: '#37872D'
};
}
const themeType: GrafanaThemeType = 'dark';
const themeColor = getColorForTheme(color, themeType);
// after
const color = 'green';
const theme: GrafanaTheme = useTheme();
const themeColor = getColorForTheme(color, theme);
```
## From version 6.x.x to 7.0.0
### What's new in Grafana 7.0?
Grafana 7.0 introduced a whole new plugin platform based on React. The new platform supersedes the previous Angular-based plugin platform.
Plugins built using Angular still work for the foreseeable future, but we encourage new plugin authors to develop with the new platform.
#### New data format
Along with the move to React, the new plugin platform introduced a new internal data format called [data frames](data-frames.md).
Previously, data source plugins could send data either as time series or tables. With data frames, data sources can send any data in a table-like structure. This gives you more flexibility to visualize your data in Grafana.
#### Improved TypeScript support
While the previous Angular-based plugin SDK did support TypeScript, for the React platform, weve greatly improved the support. All our APIs are now TypeScript, which might require existing code to update to the new stricter type definitions. Grafana 7.0 also introduced several new APIs for plugin developers that take advantage of many of the new features in Grafana 7.0.
#### Grafana Toolkit
With Grafana 7.0, we released a new tool for making it easier to develop plugins. Before, youd use Gulp, Grunt, or similar tools to generate the minified assets. Grafana Toolkit takes care of building and testing your plugin without complicated configuration files.
For more information, refer to [@grafana/toolkit](https://www.npmjs.com/package/@grafana/toolkit).
#### Field options
Grafana 7.0 introduced the concept of _field options_, a new way of configuring your data before it gets visualized. Since this was not available in previous versions, any plugin that enables field-based configuration will not work in previous versions of Grafana.
For plugins prior to Grafana 7.0, all options are considered _Display options_. The tab for field configuration isn't available.
#### Backend plugins
While backend plugins were available as an experimental feature in previous versions of Grafana, the support has been greatly improved for Grafana 7. Backend plugins for Grafana 7.0 are backwards-compatible and will continue to work. However, the old backend plugin system has been deprecated, and we recommend that you use the new SDK for backend plugins.
Since Grafana 7.0 introduced signing of backend plugins, community plugins wont load by default if theyre unsigned.
### Migrate a plugin from Angular to React
If youre looking to migrate a plugin to the new plugin platform, then we recommend that you release it under a new major version. Consider keeping a release branch for the previous version to be able to roll out patch releases for versions prior to Grafana 7.
While there's no 1-to-1 migration path from an Angular plugin to the new React platform, from early adopters, weve learned that one of the easiest ways to migrate is to:
1. Create a new branch called `migrate-to-react`.
1. Start from scratch with one of the templates provided by Grafana Toolkit.
1. Move the existing code into the new plugin incrementally, one component at a time.
#### Migrate a panel plugin
Prior to Grafana 7.0, you would export a MetricsPanelCtrl from module.ts.
**src/module.ts**
```ts
import { MetricsPanelCtrl } from 'grafana/app/plugins/sdk';
class MyPanelCtrl extends MetricsPanelCtrl {
// ...
}
export { MyPanelCtrl as PanelCtrl };
```
Starting with 7.0, plugins now export a PanelPlugin from module.ts where MyPanel is a React component containing the props from PanelProps.
**src/module.ts**
```ts
import { PanelPlugin } from '@grafana/data';
export const plugin = new PanelPlugin<MyOptions>(MyPanel);
```
**src/MyPanel.tsx**
```ts
import { PanelProps } from '@grafana/data';
interface Props extends PanelProps<SimpleOptions> {}
export function MyPanel({ options, data, width, height }: Props) {
// ...
}
```
#### Migrate a data source plugin
While all plugins are different, we'd like to share a migration process that has worked for some of our users.
1. Define your configuration model and `ConfigEditor`. For many plugins, the configuration editor is the simplest component so it's a good candidate to start with.
1. Implement the `testDatasource()` method on the class that extends `DataSourceApi` using the settings in your configuration model to make sure you can successfully configure and access the external API.
1. Implement the `query()` method. At this point, you can hard-code your query, because we havent yet implemented the query editor. The `query()` method supports both the new data frame response and the old TimeSeries response, so dont worry about converting to the new format just yet.
1. Implement the `QueryEditor`. How much work this requires depends on how complex your query model is.
By now, you should be able to release your new version.
To fully migrate to the new plugin platform, convert the time series response to a data frame response.
#### Migrate to data frames
Before 7.0, data source and panel plugins exchanged data using either time series or tables. Starting with 7.0, plugins use the new data frame format to pass data from data sources to panels.
Grafana 7.0 is backward compatible with the old data format used in previous versions. Panels and data sources using the old format will still work with plugins using the new data frame format.
The `DataQueryResponse` returned by the `query` method can be either a [LegacyResponseData](https://github.com/grafana/grafana/blob/main/packages/grafana-data/src/types/datasource.ts#L419) or a [DataFrame](https://github.com/grafana/grafana/blob/main/packages/grafana-data/src/types/dataFrame.ts#L200).
The [toDataFrame()](https://github.com/grafana/grafana/blob/main/packages/grafana-data/src/dataframe/processDataFrame.ts#L309) function converts a legacy response, such as `TimeSeries` or `Table`, to a `DataFrame`. Use it to gradually move your code to the new format.
```ts
import { toDataFrame } from '@grafana/data';
```
```ts
async query(options: DataQueryRequest<MyQuery>): Promise<DataQueryResponse> {
return {
data: options.targets.map(query => {
const timeSeries: TimeSeries = await doLegacyRequest(query);
return toDataFrame(timeSeries);
}
};
}
```
### Troubleshoot plugin migration
As of Grafana 7.0, backend plugins can now be cryptographically signed to verify their origin. By default, Grafana ignores unsigned plugins. For more information, refer to [Allow unsigned plugins]({{< relref "../../administration/plugin-management/#allow-unsigned-plugins" >}}).

View File

@@ -1,41 +0,0 @@
---
aliases:
- ../../plugins/developing/migration-guide
keywords:
- grafana
- plugins
- migration
- plugin
- documentation
title: Migration guides
---
<script>
(function () {
// Previously all the migration docs were on a single page, and the different sections could be linked using URL hashes.
var anchorRedirects = {
"migrate-a-plugin-from-angular-to-react": "./angular-react/",
"from-version-62x-to-740": "./v6.x-v7.x#from-version-62x-to-740",
"from-version-65x-to-730": "./v6.x-v7.x#from-version-65x-to-730",
"from-version-6xx-to-700": "./v6.x-v7.x/",
"migrate-to-data-frames": "./v6.x-v7.x/",
"troubleshoot-plugin-migration": "./v6.x-v7.x/",
"from-version-7xx-to-8xx": "./v7.x-v8.x/",
"from-version-83x-to-84x": "./v8.3.x-8.4.x/",
"from-version-8x-to-9x": "./v8.x-v9.x/",
"from-version-91x-to-92x": "./v9.1.x-v9.2.x/",
"from-version-93x-to-94x": "./v9.3.x-9.4.x/",
};
var hash = window.location.hash.substring(1);
var redirectTo = anchorRedirects[hash];
if (redirectTo) {
window.location.replace(redirectTo);
}
})();
</script>
# Plugin migration guide
The following guides help you identify the steps required to update a plugin following changes between versions of Grafana.
{{< section menuTitle="true">}}

View File

@@ -1,73 +0,0 @@
---
title: Configuring plugin spellcheck
description: Internal docs on how to setup the plugin spellcheck
draft: true
---
# Configuring plugin spellcheck
> This process is applicable only for grafana maintained plugins and only if the plugins are activated in drone.grafana.net for CI process.
## What it is and why it is required
The spellcheck CI step performs basic spellcheck against the plugin code and documentation.\
It helps us to avoid showing things like this to our customers:
![image](https://user-images.githubusercontent.com/1436174/208397307-4270cb57-b538-4c68-8b0f-67ab5d3b8dad.png)
At the moment spellcheck is mandatory for all internal plugins.
Under the hood, the pipeline uses [cspell npm package](https://www.npmjs.com/package/cspell) to perform the spellcheck.
## Steps to configure spellcheck
If you ended up here following the link from the failing CI then most probably you don't have spellcheck configured for your plugin. Follow the below steps to set it up.
1. Install cspell package to your plugin's repo:
```bash
yarn add -D cspell@6.13.3
```
3. Add `spellcheck` command to the `scripts` section in `package.json` of your plugin:
```
"spellcheck": "cspell -c cspell.config.json \"**/*.{ts,tsx,js,go,md,mdx,yml,yaml,json,scss,css}\""
```
3. Create a `cspell.config.json` file in the repo root folder and add a basic config there:
```json
{
"ignorePaths": [
"coverage/**",
"cypress/**",
"dist/**",
"go.sum",
"mage_output_file.go",
"node_modules/**",
"provisioning/**/*.yaml",
"src/dashboards/*.json",
"**/testdata/**/*.json",
"**/testdata/**/*.jsonc",
"vendor/**",
"cspell.config.json",
"package.json",
"yarn.lock",
"docker-compose*.yaml",
"docker-compose*.yml"
],
"ignoreRegExpList": [
// ignore multiline imports
"import\\s*\\((.|[\r\n])*?\\)",
// ignore single line imports
"import\\s*.*\".*?\""
],
"words": ["grafana", "datasource", "datasources"]
}
```
4. Run `yarn spellcheck` to see if there are any misspellings
5. If errors found, either fix them or add to `ignorePaths` or `words` section of the `cspell.config.json` created earlier
Sample PR to add spellcheck to your repo: https://github.com/grafana/athena-datasource/pull/185/files

Some files were not shown because too many files have changed in this diff Show More