Compare commits

...

57 Commits

Author SHA1 Message Date
grafana-delivery-bot[bot]
252761264e Release: Bump version to 10.3.3 (#90)
Co-authored-by: grafana-delivery-bot[bot] <132647405+grafana-delivery-bot[bot]@users.noreply.github.com>
2024-02-02 10:14:58 -05:00
Xavi Lacasa
3f111809aa Add email verification when updating user email 2024-01-22 23:38:26 +01:00
grafana-delivery-bot[bot]
f0778dd147 [v10.3.x] Elasticsearch: Fix creating of legend so it is backward compatible with frontend produced frames (#81786)
Elasticsearch: Fix creating of legend so it is backward compatible with frontend produced frames (#81708)

* Elasticsearch: Fix creating of legend so it is backward compatible with frontend produced frames

* Update tests

(cherry picked from commit f2936d6695)

Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com>
2024-02-02 14:00:39 +02:00
grafana-delivery-bot[bot]
069704b39a [v10.3.x] Alerting docs: rename provisioning files (#81729)
Alerting docs: rename provisioning files (#81722)

(cherry picked from commit 95f90127ad)

Co-authored-by: brendamuir <100768211+brendamuir@users.noreply.github.com>
2024-02-02 10:06:10 +02:00
grafana-delivery-bot[bot]
5c10afaf63 [v10.3.x] Docs: add missing supported visualizations (#81754)
Docs: add missing supported visualizations (#81668)

* Added Supported visualizations sections and missing settings for value mappings

* Updated supported visualizations table and added docs ref links

* Updated supported visualizations table

* Removed placeholder headings and accidentally added section to data links page

* Added missing visualization

(cherry picked from commit 10bde9ce9c)

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
2024-02-01 19:28:58 -05:00
grafana-delivery-bot[bot]
c0049dcbd6 [v10.3.x] Fix typos (#81737)
Fix typos (#81270)

(cherry picked from commit 021aca256c)

Co-authored-by: lean.dev <34773040+leandro-deveikis@users.noreply.github.com>
2024-02-01 20:29:57 +02:00
Ivan Ortega Alba
be850d677a [v10.3.x] ShareModal: Fixes url sync issue that caused issue with save drawer (#81721)
ShareModal: Fixes url sync issue that caused issue with save drawer (#81706)

(cherry picked from commit 7c2622a4f1)

Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
2024-02-01 16:45:13 +01:00
grafana-delivery-bot[bot]
c03a7b9806 [v10.3.x] Alerting docs: corrects save text (#81703)
Alerting docs: corrects save text (#81700)

* Alerting docs: corrects save text

* updates numbering

(cherry picked from commit bac4c7fb32)

Co-authored-by: brendamuir <100768211+brendamuir@users.noreply.github.com>
2024-02-01 14:10:36 +01:00
grafana-delivery-bot[bot]
cf586a09ae [v10.3.x] Add timeout parameter to the example (#81600)
Add timeout parameter to the example (#80921)

Adding the http timeout parameter to the example to know where  is needed in the yaml configuration.

(cherry picked from commit 5c0d7749eb)

Co-authored-by: ausias-armesto <ausiasarmesto@gmail.com>
2024-01-31 07:01:13 -08:00
grafana-delivery-bot[bot]
18e510b027 [v10.3.x] Update Trace to Logs docs in configure-tempo-data-source.md (#81598)
Update Trace to Logs docs in configure-tempo-data-source.md (#79913)

* Update configure-tempo-data-source.md

Trace to logs documentation is unclear on a couple things. I think the context I've added will help people get things working a little easier.

* remove misunderstanding.

* Adds commas

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

---------

Co-authored-by: Kim Nylander <104772500+knylander-grafana@users.noreply.github.com>
(cherry picked from commit df59f01cc3)

Co-authored-by: Angelo Manos <angelo@angelomanos.com>
2024-01-30 13:00:35 -08:00
Isabel
5ff228aeb6 [v10.3.x] Docs: restructure manage dashboards page (#81587)
Docs: restructure manage dashboards page (#81311)

* Added import and troubleshoot dashboards pages

* Moved import dashboards to build dashboards folder

* Updated import dashboards content

* Updated manage dashboards page

* Updated troublshooting dashboards page

* Finalized text for Import dashboards and moved orphaned content to Sharing page

* Made general copy edits to Troubleshooting dashboards

* Moved More examples heading and content from Troubleshooting to Import

* General copy edits to Troubleshooting

* Fixed broken links and made small copy edits

* Fixed broken link

* Removed note and replaced with plain text description of Dashboards page

Added to do for clarifying display of Shared with me section

* Deleted orphaned export content; to be rolled in later

* Copy edits

* Updated Shared with me section

* Copy edits

* Apply suggestions from code review

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

---------

Co-authored-by: Jack Baldry <jack.baldry@grafana.com>
(cherry picked from commit fb1368d1ef)
2024-01-30 11:57:46 -05:00
grafana-delivery-bot[bot]
557b86804e [v10.3.x] updated Grafana Open Source documentation (#81515)
updated Grafana Open Source documentation (#80357)

Added missing installation section to run Grafana on Kubernetes

(cherry picked from commit 4e6b0fd9ce)

Co-authored-by: Usman Ahmad <usman.ahmad@grafana.com>
2024-01-29 22:16:19 +02:00
grafana-delivery-bot[bot]
3d2005cd9b [v10.3.x] Field: Fix perf regression in getUniqueFieldName() (#81415)
Field: Fix perf regression in getUniqueFieldName() (#81323)

Co-authored-by: nmarrs <nathanielmarrs@gmail.com>
(cherry picked from commit 0530021396)

Co-authored-by: Leon Sorokin <leeoniya@gmail.com>
2024-01-26 16:56:57 -06:00
grafana-delivery-bot[bot]
7bdc53053b [v10.3.x] Docs: time range copy paste (#81413)
Docs: time range copy paste (#81408)

Added new entry and deleted internal enablement video notes

(cherry picked from commit 1213b66188)

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
2024-01-26 16:42:33 -05:00
grafana-delivery-bot[bot]
3377dc411c [v10.3.x] Docs: add saved dashboard guidance (#81411)
Docs: add saved dashboard guidance (#81406)

* Added saved dashboard guidance

* Ran prettier

(cherry picked from commit 42c9b582e0)

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
2024-01-26 16:30:28 -05:00
Ieva
534b23eb9d [v10.3.x] RBAC: Annotation permission migration (#81399)
RBAC: Annotation permission migration (#78899)

* add annotation permissions to dashboard managed role and add migrations for annotation permissions

* fix a bug with conditional access level definitions

* add tests

* Update pkg/services/sqlstore/migrations/accesscontrol/dashboard_permissions.go

Co-authored-by: Gabriel MABILLE <gamab@users.noreply.github.com>

* apply feedback

* add batching, fix tests and a typo

* add one more test

* undo unneeded change

* undo unwanted change

* only check the default basic permissions for non-OSS instances

* account for all wildcards and simplify the check a bit

* error handling and extra conditionals to avoid test failures

* fix a bug with admin permissions not appearing for folders

* fix the OSS check

---------

Co-authored-by: Gabriel MABILLE <gamab@users.noreply.github.com>
(cherry picked from commit 048d1e7c86)
2024-01-26 22:28:25 +02:00
grafana-delivery-bot[bot]
e6d2e4d8fe [v10.3.x] Logs: Fix toggleable filters to be applied for specified query (#81376)
Logs: Fix toggleable filters to be applied for specified query (#81368)

(cherry picked from commit 8c212a1952)

Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com>
2024-01-26 16:11:13 +01:00
grafana-delivery-bot[bot]
537d7b46cf [v10.3.x] Loki: Fix label not being added to all subexpressions (#81363)
Loki: Fix label not being added to all subexpressions (#81360)

(cherry picked from commit 9c728def38)

Co-authored-by: Sven Grossmann <sven.grossmann@grafana.com>
2024-01-26 14:21:22 +01:00
grafana-delivery-bot[bot]
330d3adae2 [v10.3.x] Docs: restructure Configure value mappings page (#81305)
Docs: restructure Configure value mappings page (#80103)

* Consolidated four add mappings tasks into one

* Moved images from tasks to types of value mappings section

* Removed edit value mappings section

* Moved sentence about reordering mappings to intro section

* Docs: Add to and update Configure value mappings page (#80104)

* Added to do notes

* Updated intro text and screenshot

* More intro edits

* Updated Types of value mappings section

Replaced bullet list items with headings

Updated text and screenshots of section

* Updated Add a value mapping task

* Recast sentence to remove passive voice

* Replaced local image files with images on admin

(cherry picked from commit c696b5e1dd)

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
2024-01-25 14:43:55 -05:00
grafana-delivery-bot[bot]
3417e99a19 [v10.3.x] Docs: fix broken link (#81289)
Docs: fix broken link (#81285)

Fixed broken link

(cherry picked from commit a9731846cc)

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
2024-01-25 12:07:06 -05:00
grafana-delivery-bot[bot]
f2f9ece03a [v10.3.x] Alerting docs: recovery threshold (#81239)
Alerting docs: recovery threshold (#81069)

* Alerting docs: recovery threshold

* ran prettier

* Adds note that only available in oss

* ran prettier

(cherry picked from commit 030a68bbf7)

Co-authored-by: brendamuir <100768211+brendamuir@users.noreply.github.com>
2024-01-25 10:35:25 +01:00
grafana-delivery-bot[bot]
8abe04662b [v10.3.x] Explore: Set default time range to now-1h (#81227)
Explore: Set default time range to now-1h (#81135)

Update default time range in Explore back to now-1h

(cherry picked from commit ebe8c005ce)

Co-authored-by: Piotr Jamróz <pm.jamroz@gmail.com>
2024-01-25 09:11:00 +01:00
grafana-delivery-bot[bot]
8ce96414b0 [v10.3.x] [DOC] Fix broken link tempo data source (#81213)
[DOC] Fix broken link tempo data source (#81126)

* Fix broken link tempo data source

* Use docs/reference shortcode

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

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

---------

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

Co-authored-by: Kim Nylander <104772500+knylander-grafana@users.noreply.github.com>
2024-01-24 16:54:52 -06:00
grafana-delivery-bot[bot]
5fcfade7f0 [v10.3.x] Update make docs procedure (#81182)
Co-authored-by: grafanabot <bot@grafana.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-01-24 17:13:35 +00:00
grafana-delivery-bot[bot]
4e69ce0830 [v10.3.x] docs: add grafana video to install grafana page (#81178)
docs: add grafana video to install grafana page (#80237)

(cherry picked from commit f3bb16c598)

Co-authored-by: Marie Cruz <mdcruz@users.noreply.github.com>
2024-01-24 16:15:31 +00:00
grafana-delivery-bot[bot]
1c8d8b35c2 [v10.3.x] Stop README being built into website (#81173)
Co-authored-by: Jack Baldry <jack.baldry@grafana.com>
2024-01-24 15:41:30 +00:00
grafana-delivery-bot[bot]
f4cf504009 [v10.3.x] Added Descope as an OAuth2 provider (#81165)
Added Descope as an OAuth2 provider (#80050)

* added Descope as an OAuth2 provider

Added docs for customers of ours that have asked us how to use Descope with Grafana. We wanted to make sure they can easily find these docs on both our website and Grafana's.

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

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

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

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

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

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

* Changed note to use admonition

* Prettier

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

---------

Signed-off-by: Jack Baldry <jack.baldry@grafana.com>
Co-authored-by: Ieva <vasiljeva.ieva@gmail.com>
Co-authored-by: lwandz13 <126723338+lwandz13@users.noreply.github.com>
Co-authored-by: Jack Baldry <jack.baldry@grafana.com>
(cherry picked from commit f726ea1e52)

Co-authored-by: Kevin J Gao <32936811+gaokevin1@users.noreply.github.com>
2024-01-24 09:02:46 -06:00
grafana-delivery-bot[bot]
b6ce5e5885 [v10.3.x] Chore: Fix typo in docs workflow (#81113)
Chore: Fix typo in docs workflow (#81111)

Fix typo

(cherry picked from commit ed2647b742)

Co-authored-by: Andreas Christou <andreas.christou@grafana.com>
2024-01-23 17:02:08 +00:00
grafana-delivery-bot[bot]
403d00b0e4 Release: Bump version to 10.3.2 (#81108)
"Release: Updated versions in package to 10.3.2"

Co-authored-by: grafana-delivery-bot[bot] <132647405+grafana-delivery-bot[bot]@users.noreply.github.com>
2024-01-23 18:14:18 +02:00
grafana-delivery-bot[bot]
509313715a [v10.3.x] Changelog: Updated changelog for 10.3.1 (#81106)
Changelog: Updated changelog for 10.3.1 (#81105)

* Changelog: Updated changelog for 10.3.1

* Update 10.3.1 CHANGELOG

---------

Co-authored-by: grafanabot <bot@grafana.com>
Co-authored-by: Andreas Christou <andreas.christou@grafana.com>
(cherry picked from commit cbdbdf72e5)

Co-authored-by: grafana-delivery-bot[bot] <132647405+grafana-delivery-bot[bot]@users.noreply.github.com>
2024-01-23 16:57:12 +01:00
grafana-delivery-bot[bot]
3e6b3a69b4 [v10.3.x] Changelog: Updated changelog for 10.3.0 (#81104)
Changelog: Updated changelog for 10.3.0 (#81100)

* Changelog: Updated changelog for 10.3.0

* Add release note

---------

Co-authored-by: grafanabot <bot@grafana.com>
Co-authored-by: Andreas Christou <andreas.christou@grafana.com>
(cherry picked from commit f2e1e78b37)

Co-authored-by: grafana-delivery-bot[bot] <132647405+grafana-delivery-bot[bot]@users.noreply.github.com>
2024-01-23 17:51:30 +02:00
grafana-delivery-bot[bot]
34709d74cc [v10.3.x] Tempo TraceQl Editor update request #8382 (#81093)
Tempo TraceQl Editor update request #8382 (#80112)

* Tempo TraceQl Editor update request #8382

* Docs: Typo

* Docs: Typo 2 codespell lint

* Update docs/sources/shared/datasources/tempo-editor-traceql.md

* Update docs/sources/shared/datasources/tempo-editor-traceql.md

* Update docs/sources/shared/datasources/tempo-editor-traceql.md

---------

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

Co-authored-by: Jara Suárez de Puga García <jara.suarezdepuga@grafana.com>
2024-01-23 07:07:59 -08:00
grafana-delivery-bot[bot]
ea8a2c4083 [v10.3.x] Docs: configure grafana database configuration MYSQL (#81087)
Docs: configure grafana database configuration MYSQL  (#80939)

* Docs database max_open_conn MYSQL

* Docs: suggestion max_connections

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

---------

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>
(cherry picked from commit 8435e16215)

Co-authored-by: Jara Suárez de Puga García <jara.suarezdepuga@grafana.com>
2024-01-23 08:23:17 -06:00
grafana-delivery-bot[bot]
28cf2b300d [v10.3.x] Security: Fix vulnerability GHSA-9763-4f94-gfch (#81078)
Security: Fix vulnerability GHSA-9763-4f94-gfch (#80952)

chore: upgrade cloudfare circl dependency

Signed-off-by: Pier <53210578+pie-r@users.noreply.github.com>
(cherry picked from commit a8dec1916b)

Co-authored-by: Pier <53210578+pie-r@users.noreply.github.com>
2024-01-23 14:56:38 +01:00
grafana-delivery-bot[bot]
835744673c [v10.3.x] Alerting docs: updates eval group and provisioning topics for support (#81075)
Alerting docs: updates eval group and provisioning topics for support (#81066)

(cherry picked from commit f9486ad2ee)

Co-authored-by: brendamuir <100768211+brendamuir@users.noreply.github.com>
2024-01-23 14:28:09 +01:00
grafana-delivery-bot[bot]
0177550993 [v10.3.x] Elasticsearch: Fix URL creation and allowlist for /_mapping requests (#81057)
Elasticsearch: Fix URL creation and allowlist for `/_mapping` requests (#80970)

* Elasticsearch: Fix URL creation for mapping requests

* remove leading slash by default

* add comment for es route

* hardcode `_mapping`

* update doc

(cherry picked from commit 3d033839d7)

Co-authored-by: Sven Grossmann <sven.grossmann@grafana.com>
2024-01-23 13:15:58 +01:00
grafana-delivery-bot[bot]
b55cd1288c [v10.3.x] docs: What’s new & Upgrade guide 10.3 (#81028)
docs: What’s new & Upgrade guide 10.3 (#80399)

* initial commit for v10.3 whats new

* Added breaking changes guide and updated What's new doc

* Added 10.2.3 in frontmatter of files

* Added content from What's new in Cloud

* Added note about 10.203 and breaking changes section

* Made formatting edits

* Added 10.2.3 test note

* Replaced 10.2.3 notes with asterisks

* Added tag note

* Move reporting item out of D&V section

* Added breaking changes

* Fixed availability notes

* Moved feature from Traces to Profiles and removed Traces section

* Reordered sections

* Replaced Cloud links with OSS links and relrefs with full URLs

* Updated template

* Copy edit

* Clarified outstanding questions

* Updated data source admin permissions note

* Removed duplicate alerting items

* add InfluxDB SQL support

* Ran prettier

* Added availability, video and contributor info

* Ran prettier

* Added youtube video links

* Removed old video link

---------

Co-authored-by: nmarrs <nathanielmarrs@gmail.com>
Co-authored-by: ismail simsek <ismailsimsek09@gmail.com>
(cherry picked from commit 2a53ae637e)

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
2024-01-22 18:32:09 -05:00
grafana-delivery-bot[bot]
04b3a236f3 [v10.3.x] Docs: update per Support request (#81016)
Docs: update per Support request (#80845)

* update per support request, additional enhancements

* ran prettier

(cherry picked from commit 7375e64275)

Co-authored-by: lwandz13 <126723338+lwandz13@users.noreply.github.com>
2024-01-22 13:37:26 -06:00
Tania
c2f0203662 [v10.3.x] Nested Folders: Add back syncing of folders between folder and dashboard tbls (#81010)
Nested Folders: Add back syncing of folders between folder and dashboard tbls (#80972)

Add back syncing of folders between folder and dashboard tbls

This partially reverts commit 06d2ae3ada.

(cherry picked from commit 07aa173939)
2024-01-22 19:59:47 +01:00
Sofia Papagiannaki
b168ca8a9a [v10.3.x] Folders: Fix creating/updating a folder whose title has leading and trailing spaces (#81006)
Folders: Fix creating/updating a folder whose title has leading and trailing spaces (#80909)

* Add tests

* Folders: Fix creating folder whose title has leading and trailing spaces

* Fix folder update

* Remove redundant argument

* Fix test

(cherry picked from commit 4243079cb5)
2024-01-22 20:50:54 +02:00
grafana-delivery-bot[bot]
c57ba08e28 [v10.3.x] Docs: restructure Configure data links page (#80925)
Docs: restructure Configure data links page (#80100)

* Moved content under Data links heading to intro of page and deleted heading

* Made headings for data link variable types H3s nesting under Data link variables

* Removed unecessary update and delete data links sections

* Made old intro sentence part of new intro

* Made Add a data link section an H2

* Removed unecessary typeahead suggestions section

* Moved variables into tables and capitalized first word of descriptions

* Docs: Edit Configure data links page (#80101)

* Added content update notes

* Rewrote Add a data link section per style guidelines

* Copy edits

* Copy edits

* Copy edits

* Copy edited intro text, removed instances of e.g., and replaced OSS links with Cloud links

* Standardized the format of variables in tables

* Added images (locally) and clarified context menu behaviour

* Removed working notes

* Fixed typo

* Removed images from local and updated image pathways

(cherry picked from commit 9fc789d901)

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
2024-01-19 15:53:18 -05:00
Dimitris Sotirakis
0ec97b3878 [v10.3.x] ImagePullSecrets: Add GAR secret to image_pull_secret in .drone.yml (#80919)
`ImagePullSecrets`: Add `GAR` secret to `image_pull_secret` in `.drone.yml` (#80912)

* Add GAR secret to image_pull_secret

* Fix starlark fmt

(cherry picked from commit 65104a7efa)
2024-01-19 19:59:21 +02:00
grafana-delivery-bot[bot]
38732d474b [v10.3.x] Docs: move best practices page (#80888)
Docs: move best practices page (#80844)

Moved best practices page

(cherry picked from commit 35ade8974f)

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
2024-01-19 08:39:07 -05:00
grafana-delivery-bot[bot]
35a2b14c4b [v10.3.x] Elasticsearch: Fix showing of logs when __source is log message field (#80863)
Elasticsearch: Fix showing of logs when `__source` is log message field (#80804)

Elasticsearch: Fix showing of logs whe __source is log message field
(cherry picked from commit 759c088ac5)

Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com>
2024-01-19 13:02:41 +01:00
grafana-delivery-bot[bot]
d19e5ec49f [v10.3.x] Explore: Re-enable basic e2e test for Explore (#80713)
Explore: Re-enable basic e2e test for Explore (#80617)

Re-enable basic test for Explore

(cherry picked from commit 322cd74b9c)

Co-authored-by: Piotr Jamróz <pm.jamroz@gmail.com>
2024-01-19 11:00:17 +01:00
grafana-delivery-bot[bot]
bfbe603bb2 [v10.3.x] Update make docs procedure (#80865)
Co-authored-by: grafanabot <bot@grafana.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-01-19 11:36:50 +02:00
grafana-delivery-bot[bot]
8bf3055cb6 [v10.3.x] Update _index.md (#80812)
Update _index.md (#79606)

Just suggesting a typo fix - change "an telemetry" to "a telemetry"

(cherry picked from commit 9f2775e771)

Co-authored-by: aalapk <32711124+aalapk@users.noreply.github.com>
2024-01-18 08:14:20 -06:00
grafana-delivery-bot[bot]
21e1008976 [v10.3.x] RBAC: Clean up data source permissions after data source deletion (#80723)
RBAC: Clean up data source permissions after data source deletion (#80654)

* clean up data source permissions after data source deletion

* remove a comment

(cherry picked from commit def1b05a93)

Co-authored-by: Ieva <ieva.vasiljeva@grafana.com>
2024-01-17 15:47:37 +02:00
grafana-delivery-bot[bot]
22d91ddb0b [v10.3.x] Docs: Updated anon user and dashboard access (#80687)
Docs:  Updated anon user and dashboard access (#80400)

* Clarified anon user and viewer role, style updates.

* fixed spelling error

(cherry picked from commit 00b954203d)

Co-authored-by: lwandz13 <126723338+lwandz13@users.noreply.github.com>
2024-01-16 17:24:36 -06:00
grafana-delivery-bot[bot]
570736eb23 [v10.3.x] Docs: add more time zone guidance (#80677)
Docs: add more time zone guidance (#79595)

* Created report time zone section with added guidance

* Added more information

* Updated from review suggestions

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

Co-authored-by: Agnès Toulet <35176601+AgnesToulet@users.noreply.github.com>

* Ran prettier

---------

Co-authored-by: Agnès Toulet <35176601+AgnesToulet@users.noreply.github.com>
(cherry picked from commit f9dcc9ff90)

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
2024-01-16 17:04:47 -05:00
grafana-delivery-bot[bot]
7b06079f0d [v10.3.x] Annotations: Split cleanup into separate queries and deletes to avoid deadlocks on MySQL (#80486)
* 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 timing change

* remove log lines, fixed in main

* Two more log lines

---------

Co-authored-by: Alexander Weaver <weaver.alex.d@gmail.com>
2024-01-16 14:37:00 -06:00
grafana-delivery-bot[bot]
8ba22b11cf [v10.3.x] updated grafana docker video timestamp (#80663)
updated grafana docker video timestamp (#80659)

Update the documentation page:

https://grafana.com/docs/grafana/latest/setup-grafana/installation/docker/

Added the time when the actual demo starts.

(cherry picked from commit 739cba6eb9)

Co-authored-by: Usman Ahmad <usman.ahmad@grafana.com>
2024-01-16 11:36:55 -06:00
grafana-delivery-bot[bot]
b0f6404e0a [v10.3.x] Update Grafana Kubernetes installation page (#80650)
Update Grafana Kubernetes installation page (#80569)

Removed the Vimeo and added the YouTube link after an internal discussion with the team.

(cherry picked from commit 0f093c1463)

Co-authored-by: Usman Ahmad <usman.ahmad@grafana.com>
2024-01-16 10:58:29 -06:00
grafana-delivery-bot[bot]
6870f2381e [v10.3.x] Release: Deprecate latest.json and replace with api call to grafana.com (#80602)
Release: Deprecate latest.json and replace with api call to grafana.com (#80537)

* remove latest.json and replace with api call to grafana.com

* remove latest.json

* Revert "remove latest.json"

This reverts commit bcff43d898.

* Revert "remove latest.json and replace with api call to grafana.com"

This reverts commit 02b867d84e.

* add deprecation message to latest.json

(cherry picked from commit 127decee1e)

Co-authored-by: Ashley Harrison <ashley.harrison@grafana.com>
2024-01-16 12:09:22 +00:00
Ashley Harrison
7c2e5376c8 [v10.3.x] NestedFolderPicker: separate toggle to force enable picker without (#80549)
* NestedFolderPicker: separate toggle to force enable picker without `nestedFolders` (#80461)

* separate nestedFolderPickerOverride toggle to force enable it without nestedFolders

* let's call it newFolderPicker

* update unit tests and keyboard handling

* reduce spacing when no folder open chevron

---------

Co-authored-by: Josh Hunt <joshhunt@users.noreply.github.com>
(cherry picked from commit ec53487c99)

* add config import to NestedFolderPicker
2024-01-16 11:39:22 +00:00
grafana-delivery-bot[bot]
4ba9afa45f [v10.3.x] Auth: Use cfg.Raw in OAuthStrategy for loading settings (#80441)
Auth: Use cfg.Raw in OAuthStrategy for loading settings (#80136)

Use cfg.Raw in OAuthStrategy, remove unnecessary tests

(cherry picked from commit eae6adf002)

Co-authored-by: Misi <mgyongyosi@users.noreply.github.com>
2024-01-12 14:35:02 +01:00
grafana-delivery-bot[bot]
be211fbccb [v10.3.x] Loki: Fix bug duplicating parsed labels across multiple log lines (#80423)
Loki: Fix bug duplicating parsed labels across multiple log lines (#80292)

(cherry picked from commit e1aa8a95d9)

Co-authored-by: Sven Grossmann <sven.grossmann@grafana.com>
2024-01-12 12:19:24 +02:00
183 changed files with 5844 additions and 1172 deletions

View File

@@ -5,7 +5,8 @@ depends_on: []
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: pr-verify-drone
node:
@@ -55,7 +56,8 @@ depends_on: []
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: pr-verify-starlark
node:
@@ -105,7 +107,8 @@ depends_on: []
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: pr-test-frontend
node:
@@ -184,7 +187,8 @@ depends_on: []
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: pr-lint-frontend
node:
@@ -273,7 +277,8 @@ depends_on: []
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: pr-test-backend
node:
@@ -379,7 +384,8 @@ depends_on: []
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: pr-lint-backend
node:
@@ -474,7 +480,8 @@ depends_on: []
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: pr-build-e2e
node:
@@ -756,7 +763,8 @@ depends_on: []
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: pr-integration-tests
node:
@@ -1020,7 +1028,8 @@ depends_on: []
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: pr-docs
node:
@@ -1094,7 +1103,8 @@ depends_on: []
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: pr-shellcheck
node:
@@ -1136,7 +1146,8 @@ clone:
retries: 3
depends_on: []
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: pr-swagger-gen
node:
@@ -1199,7 +1210,8 @@ depends_on: []
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: pr-integration-benchmarks
node:
@@ -1375,7 +1387,8 @@ depends_on: []
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: main-docs
node:
@@ -1450,7 +1463,8 @@ depends_on: []
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: main-test-frontend
node:
@@ -1507,7 +1521,8 @@ depends_on: []
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: main-lint-frontend
node:
@@ -1574,7 +1589,8 @@ depends_on: []
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: main-test-backend
node:
@@ -1653,7 +1669,8 @@ depends_on: []
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: main-lint-backend
node:
@@ -1727,7 +1744,8 @@ depends_on: []
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: main-build-e2e-publish
node:
@@ -2127,7 +2145,8 @@ depends_on: []
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: main-integration-tests
node:
@@ -2370,7 +2389,8 @@ depends_on:
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: main-windows
platform:
@@ -2414,7 +2434,8 @@ depends_on:
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: main-trigger-downstream
node:
@@ -2497,7 +2518,8 @@ depends_on: []
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: publish-docker-public
node:
@@ -2603,7 +2625,8 @@ depends_on: []
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: publish-artifacts-public
node:
@@ -2672,7 +2695,8 @@ depends_on: []
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: publish-npm-packages-public
node:
@@ -2737,7 +2761,8 @@ depends_on:
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: publish-packages
node:
@@ -2825,7 +2850,8 @@ depends_on:
- main-test-backend
- main-test-frontend
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: rgm-main-prerelease
node:
@@ -2900,7 +2926,8 @@ depends_on: []
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: release-whatsnew-checker
node:
@@ -2944,7 +2971,8 @@ depends_on: []
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: release-test-frontend
node:
@@ -2999,7 +3027,8 @@ depends_on: []
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: release-test-backend
node:
@@ -3076,7 +3105,8 @@ depends_on:
- release-test-backend
- release-test-frontend
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: rgm-tag-prerelease
node:
@@ -3147,7 +3177,8 @@ clone:
depends_on:
- rgm-tag-prerelease
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: rgm-tag-prerelease-windows
platform:
@@ -3211,7 +3242,8 @@ depends_on:
- rgm-tag-prerelease
- rgm-tag-prerelease-windows
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: rgm-tag-verify-prerelease-assets
node:
@@ -3256,7 +3288,8 @@ depends_on:
- release-test-backend
- release-test-frontend
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: rgm-version-branch-prerelease
node:
@@ -3321,7 +3354,8 @@ clone:
depends_on:
- rgm-version-branch-prerelease
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: rgm-prerelease-verify-prerelease-assets
node:
@@ -3360,7 +3394,8 @@ depends_on: []
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: nightly-test-frontend
node:
@@ -3413,7 +3448,8 @@ depends_on: []
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: nightly-test-backend
node:
@@ -3488,7 +3524,8 @@ depends_on:
- nightly-test-backend
- nightly-test-frontend
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: rgm-nightly-build
node:
@@ -3595,7 +3632,8 @@ clone:
depends_on:
- rgm-nightly-build
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: rgm-nightly-publish
node:
@@ -3744,7 +3782,8 @@ depends_on: []
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: testing-test-backend-windows
platform:
@@ -3796,7 +3835,8 @@ depends_on: []
environment:
EDITION: oss
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: integration-tests
node:
@@ -4019,7 +4059,8 @@ clone:
disable: true
depends_on: []
image_pull_secrets:
- dockerconfigjson
- gcr
- gar
kind: pipeline
name: publish-ci-windows-test-image
platform:
@@ -4458,7 +4499,13 @@ get:
name: .dockerconfigjson
path: secret/data/common/gcr
kind: secret
name: dockerconfigjson
name: gcr
---
get:
name: .dockerconfigjson
path: secret/data/common/gar
kind: secret
name: gar
---
get:
name: pat
@@ -4629,6 +4676,6 @@ kind: secret
name: gcr_credentials
---
kind: signature
hmac: d7e383e4bf37190a97d695ef8f91755cb8cb70fb8088a5c1f63262adcf8e4f5e
hmac: 6df571f0449f7220d208c81fe6bd5537d82afee03f2a773aaaf74af02978f56a
...

View File

@@ -55,7 +55,7 @@ jobs:
# Tags aren't necessarily made to the HEAD of the version branch.
# The documentation to be published is always on the HEAD of the version branch.
if: "steps.has-matching-release-tag.outputs.bool == 'true' && github.ref_type == 'tag'"
run: "git switch --detach origin/${{ steps.target.output.target }}.x"
run: "git switch --detach origin/${{ steps.target.outputs.target }}.x"
- name: "Publish to website repository (release)"
if: "steps.has-matching-release-tag.outputs.bool == 'true'"

View File

@@ -1,3 +1,108 @@
<!-- 10.3.1 START -->
# 10.3.1 (2024-01-22)
To resolve a technical issue within the Grafana release package management process, we are releasing both Grafana 10.3.0 and Grafana 10.3.1 simultaneously. The 10.3.1 release contains no breaking or functional changes from 10.3.0. Please refer to the [Whats New](https://grafana.com/docs/grafana/latest/whatsnew/whats-new-in-v10-3/) post for Grafana 10.3.0 for details on new features and changes in this release.
<!-- 10.3.1 END -->
<!-- 10.3.0 START -->
# 10.3.0 (2024-01-22)
To resolve a technical issue within the Grafana release package management process, we are releasing both Grafana 10.3.0 and Grafana 10.3.1 simultaneously. The 10.3.1 release contains no breaking or functional changes from 10.3.0. Please refer to the [Whats New](https://grafana.com/docs/grafana/latest/whatsnew/whats-new-in-v10-3/) post for Grafana 10.3.0 for details on new features and changes in this release.
### Features and enhancements
- **Alerting:** Guided legacy alerting upgrade dry-run. [#80071](https://github.com/grafana/grafana/issues/80071), [@JacobsonMT](https://github.com/JacobsonMT)
- **Explore:** Preserve time range when creating a dashboard panel from Explore. [#80070](https://github.com/grafana/grafana/issues/80070), [@Elfo404](https://github.com/Elfo404)
- **Explore:** Init with mixed DS if there's no root DS in the URL and queries have multiple datasources. [#80068](https://github.com/grafana/grafana/issues/80068), [@Elfo404](https://github.com/Elfo404)
- **QueryEditor:** Display error even if error field is empty. [#79943](https://github.com/grafana/grafana/issues/79943), [@idastambuk](https://github.com/idastambuk)
- **K8s:** Enable api-server by default. [#79942](https://github.com/grafana/grafana/issues/79942), [@ryantxu](https://github.com/ryantxu)
- **Parca:** Add standalone building configuration. [#79896](https://github.com/grafana/grafana/issues/79896), [@fabrizio-grafana](https://github.com/fabrizio-grafana)
- **Auth:** Hide forgot password if grafana auth is disabled. [#79895](https://github.com/grafana/grafana/issues/79895), [@Jguer](https://github.com/Jguer)
- **Plugins:** Add uninstall requested message for cloud plugins. [#79748](https://github.com/grafana/grafana/issues/79748), [@oshirohugo](https://github.com/oshirohugo)
- **Loki:** Open log context in new tab. [#79723](https://github.com/grafana/grafana/issues/79723), [@svennergr](https://github.com/svennergr)
- **Alerting:** Allow linking to library panels. [#79693](https://github.com/grafana/grafana/issues/79693), [@gillesdemey](https://github.com/gillesdemey)
- **Loki:** Drop all errors in volume requests. [#79686](https://github.com/grafana/grafana/issues/79686), [@svennergr](https://github.com/svennergr)
- **Loki Logs volume:** Added a query splitting loading indicator to the Logs Volume graph. [#79681](https://github.com/grafana/grafana/issues/79681), [@matyax](https://github.com/matyax)
- **Plugins:** Disable add new data source for incomplete install. [#79658](https://github.com/grafana/grafana/issues/79658), [@oshirohugo](https://github.com/oshirohugo)
- **RBAC:** Render team, service account and user list when a user can see entities but not roles attached to them. [#79642](https://github.com/grafana/grafana/issues/79642), [@kalleep](https://github.com/kalleep)
- **InfluxDB:** Use database input for SQL configuration instead of metadata. [#79579](https://github.com/grafana/grafana/issues/79579), [@itsmylife](https://github.com/itsmylife)
- **Tempo:** Support special characters in identifiers. [#79565](https://github.com/grafana/grafana/issues/79565), [@fabrizio-grafana](https://github.com/fabrizio-grafana)
- **Alerting:** Display "Show all" button for cloud rules. [#79512](https://github.com/grafana/grafana/issues/79512), [@VikaCep](https://github.com/VikaCep)
- **React Hook Form:** Update to v 7.49.2. [#79493](https://github.com/grafana/grafana/issues/79493), [@Clarity-89](https://github.com/Clarity-89)
- **Loki:** Add timeRange to labels requests in LogContext to reduce loading times. [#79478](https://github.com/grafana/grafana/issues/79478), [@svennergr](https://github.com/svennergr)
- **InfluxDB:** Enable SQL support by default. [#79474](https://github.com/grafana/grafana/issues/79474), [@itsmylife](https://github.com/itsmylife)
- **OAuth:** Remove accessTokenExpirationCheck feature toggle. [#79455](https://github.com/grafana/grafana/issues/79455), [@mgyongyosi](https://github.com/mgyongyosi)
- **Units:** Add scalable unit option. [#79411](https://github.com/grafana/grafana/issues/79411), [@Develer](https://github.com/Develer)
- **Alerting:** Add export mute timings feature to the UI. [#79395](https://github.com/grafana/grafana/issues/79395), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
- **Config:** Can add static headers to email messages. [#79365](https://github.com/grafana/grafana/issues/79365), [@owensmallwood](https://github.com/owensmallwood)
- **Alerting:** Drop NamespaceID from responses on unstable ngalert API endpoints in favor of NamespaceUID. [#79359](https://github.com/grafana/grafana/issues/79359), [@alexweav](https://github.com/alexweav)
- **Cloudwatch:** Update cloudwatchNewRegionsHandler to General Availability. [#79348](https://github.com/grafana/grafana/issues/79348), [@sarahzinger](https://github.com/sarahzinger)
- **Plugins:** Include Azure settings as a part of Grafana config sent in plugin requests. [#79342](https://github.com/grafana/grafana/issues/79342), [@aangelisc](https://github.com/aangelisc)
- **Plugins:** Add hide_angular_deprecation setting. [#79296](https://github.com/grafana/grafana/issues/79296), [@xnyo](https://github.com/xnyo)
- **Table:** Add select/unselect all column values to table filter. [#79290](https://github.com/grafana/grafana/issues/79290), [@ahuarte47](https://github.com/ahuarte47)
- **Anonymous:** Add configurable device limit. [#79265](https://github.com/grafana/grafana/issues/79265), [@Jguer](https://github.com/Jguer)
- **Frontend:** Detect new assets / versions / config changes. [#79258](https://github.com/grafana/grafana/issues/79258), [@ryantxu](https://github.com/ryantxu)
- **Plugins:** Add option to disable TLS in the socks proxy. [#79246](https://github.com/grafana/grafana/issues/79246), [@PoorlyDefinedBehaviour](https://github.com/PoorlyDefinedBehaviour)
- **Frontend:** Reload the browser when backend configuration/assets change. [#79057](https://github.com/grafana/grafana/issues/79057), [@torkelo](https://github.com/torkelo)
- **Chore:** Refactor dataviz aria-label e2e selectors to data-testid. [#78938](https://github.com/grafana/grafana/issues/78938), [@khushijain21](https://github.com/khushijain21)
- **SSO:** Add GitHub auth configuration page. [#78933](https://github.com/grafana/grafana/issues/78933), [@Clarity-89](https://github.com/Clarity-89)
- **PublicDashboards:** Add setting to disable the feature. [#78894](https://github.com/grafana/grafana/issues/78894), [@AgnesToulet](https://github.com/AgnesToulet)
- **Variables:** Interpolate variables used in custom variable definition. [#78800](https://github.com/grafana/grafana/issues/78800), [@torkelo](https://github.com/torkelo)
- **Table:** Highlight row on shared crosshair. [#78392](https://github.com/grafana/grafana/issues/78392), [@mdvictor](https://github.com/mdvictor)
- **Stat:** Add Percent Change Option. [#78250](https://github.com/grafana/grafana/issues/78250), [@drew08t](https://github.com/drew08t)
- **Plugins:** Add Command Palette extension point. [#78098](https://github.com/grafana/grafana/issues/78098), [@sd2k](https://github.com/sd2k)
- **Transformations:** Add frame source picker to allow transforming annotations. [#77842](https://github.com/grafana/grafana/issues/77842), [@leeoniya](https://github.com/leeoniya)
- **Pyroscope:** Send start/end with profile types query. [#77523](https://github.com/grafana/grafana/issues/77523), [@bryanhuhta](https://github.com/bryanhuhta)
- **Explore:** Create menu for short link button. [#77336](https://github.com/grafana/grafana/issues/77336), [@gelicia](https://github.com/gelicia)
- **Alerting:** Don't record annotations for mapped NoData transitions, when NoData is mapped to OK. [#77164](https://github.com/grafana/grafana/issues/77164), [@alexweav](https://github.com/alexweav)
- **Canvas:** Add Pan and Zoom. [#76705](https://github.com/grafana/grafana/issues/76705), [@drew08t](https://github.com/drew08t)
- **Alerting:** In migration, create one label per channel. [#76527](https://github.com/grafana/grafana/issues/76527), [@JacobsonMT](https://github.com/JacobsonMT)
- **Alerting:** Separate overlapping legacy and UA alerting routes. [#76517](https://github.com/grafana/grafana/issues/76517), [@JacobsonMT](https://github.com/JacobsonMT)
- **Tooltip:** Improved Timeseries and Candlestick tooltips. [#75841](https://github.com/grafana/grafana/issues/75841), [@adela-almasan](https://github.com/adela-almasan)
- **Alerting:** Support hysteresis command expression. [#75189](https://github.com/grafana/grafana/issues/75189), [@yuri-tceretian](https://github.com/yuri-tceretian)
- **Plugins:** Add update for instance plugins. (Enterprise)
- **React Hook Form:** Update to v 7.49.2. (Enterprise)
- **Plugins:** Improve cloud plugins install error treatment. (Enterprise)
### Bug fixes
- **Transformations:** Fix bug where having NaN in the input to regression analysis transformation causes all predictions to be NaN. [#80079](https://github.com/grafana/grafana/issues/80079), [@oscarkilhed](https://github.com/oscarkilhed)
- **Alerting:** Fix URL timestamp conversion in historian API in annotation mode. [#80026](https://github.com/grafana/grafana/issues/80026), [@alexweav](https://github.com/alexweav)
- **Fix:** Switch component not being styled as disabled when is checked. [#80012](https://github.com/grafana/grafana/issues/80012), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
- **Tempo:** Fix Spans table format. [#79938](https://github.com/grafana/grafana/issues/79938), [@fabrizio-grafana](https://github.com/fabrizio-grafana)
- **Gauges:** Fixing broken auto sizing. [#79926](https://github.com/grafana/grafana/issues/79926), [@torkelo](https://github.com/torkelo)
- **Barchart:** Fix percent stacking regression. [#79903](https://github.com/grafana/grafana/issues/79903), [@nmarrs](https://github.com/nmarrs)
- **Alerting:** Fix reusing last url in tab when reopening a new tab in rule detail a…. [#79801](https://github.com/grafana/grafana/issues/79801), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
- **Azure Monitor:** Fix multi-resource bug "Missing required region params, requested QueryParams: api-version:2017-12-01-preview...". [#79669](https://github.com/grafana/grafana/issues/79669), [@bossinc](https://github.com/bossinc)
- **Explore:** Fix URL sync with async queries import . [#79584](https://github.com/grafana/grafana/issues/79584), [@Elfo404](https://github.com/Elfo404)
- **Dashboards:** Skip inherited object variable names. [#79567](https://github.com/grafana/grafana/issues/79567), [@jarben](https://github.com/jarben)
- **Alerting:** Fix queries and expressions in rule view details. [#79497](https://github.com/grafana/grafana/issues/79497), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
- **Tempo:** Fix cache in TraceQL editor. [#79468](https://github.com/grafana/grafana/issues/79468), [@adrapereira](https://github.com/adrapereira)
- **Nested Folders:** Fix /api/folders pagination. [#79447](https://github.com/grafana/grafana/issues/79447), [@papagian](https://github.com/papagian)
- **Elasticsearch:** Fix modify query with backslashes. [#79430](https://github.com/grafana/grafana/issues/79430), [@svennergr](https://github.com/svennergr)
- **Cloudwatch:** Fix errors while loading queries/datasource on Safari. [#79417](https://github.com/grafana/grafana/issues/79417), [@kevinwcyu](https://github.com/kevinwcyu)
- **Stat:** Fix inconsistent center padding. [#79389](https://github.com/grafana/grafana/issues/79389), [@torkelo](https://github.com/torkelo)
- **Tempo:** Fix autocompletion with strings. [#79370](https://github.com/grafana/grafana/issues/79370), [@fabrizio-grafana](https://github.com/fabrizio-grafana)
- **Alerting:** Fix for data source filter on cloud rules. [#79327](https://github.com/grafana/grafana/issues/79327), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
- **Alerting:** Fix UI inheriting mute timings from parent when calculating the polic…. [#79295](https://github.com/grafana/grafana/issues/79295), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
- **Auth:** Fix a panic during logout when OAuth provider is not set. [#79271](https://github.com/grafana/grafana/issues/79271), [@dmihai](https://github.com/dmihai)
- **Tempo:** Fix read-only assignment. [#79183](https://github.com/grafana/grafana/issues/79183), [@fabrizio-grafana](https://github.com/fabrizio-grafana)
- **Templating:** Json interpolation of single-value default selection does not create valid json. [#79137](https://github.com/grafana/grafana/issues/79137), [@kaydelaney](https://github.com/kaydelaney)
- **Heatmap:** Fix null options migration. [#79083](https://github.com/grafana/grafana/issues/79083), [@overvenus](https://github.com/overvenus)
- **Dashboards:** Run shared queries even when source panel is in collapsed row. [#77792](https://github.com/grafana/grafana/issues/77792), [@kaydelaney](https://github.com/kaydelaney)
- **PDF:** Fix support for large panels. (Enterprise)
- **Reporting:** Fix daylight saving time support for custom schedules. (Enterprise)
- **RBAC:** Fix role assignment removal . (Enterprise)
### Breaking changes
Users who have InfluxDB datasource configured with SQL querying language must update their database information. They have to enter their `bucket name` into the database field. Issue [#79579](https://github.com/grafana/grafana/issues/79579)
Removes `NamespaceID` from responses of all GET routes underneath the path `/api/ruler/grafana/api/v1/rules` - 3 affected endpoints. All affected routes are not in the publicly documented or `stable` marked portion of the ngalert API. This only breaks clients who are directly using the unstable portion of the API. Such clients should use `NamespaceUID` rather than `NamespaceID` to identify namespaces. Issue [#79359](https://github.com/grafana/grafana/issues/79359)
<!-- 10.3.0 END -->
<!-- 10.2.3 START -->
# 10.2.3 (2023-12-18)

View File

@@ -246,7 +246,7 @@ reporting_distributor = grafana-labs
# for new versions of grafana. The check is used
# in some UI views to notify that a grafana update exists.
# This option does not cause any auto updates, nor send any information
# only a GET request to https://raw.githubusercontent.com/grafana/grafana/main/latest.json to get the latest version.
# only a GET request to https://grafana.com/api/grafana/versions/stable to get the latest version.
check_for_updates = true
# Set to false to disable all checks to https://grafana.com

View File

@@ -253,7 +253,7 @@
# for new versions of grafana. The check is used
# in some UI views to notify that a grafana update exists.
# This option does not cause any auto updates, nor send any information
# only a GET request to https://raw.githubusercontent.com/grafana/grafana/main/latest.json to get the latest version.
# only a GET request to https://grafana.com/api/grafana/versions/stable to get the latest version.
;check_for_updates = true
# Set to false to disable all checks to https://grafana.com

View File

@@ -26,6 +26,6 @@ Grafana employees can find more details in our internal docs.
## Announced deprecations.
| Name | Annoucement Date | Disabling date | Removal Date | Description | Status |
| ------------------------------------------------------------------------ | ---------------- | -------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------- | ------- |
| [Support for Mysql 5.7](https://github.com/grafana/grafana/issues/68446) | 2023-05-15 | October 2023 | | MySQL 5.7 is being deprecated in October 2023 and Grafana's policy is to test against the officially supported version. | Planned |
| Name | Announcement Date | Disabling date | Removal Date | Description | Status |
| ------------------------------------------------------------------------ | ----------------- | -------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------- | ------- |
| [Support for Mysql 5.7](https://github.com/grafana/grafana/issues/68446) | 2023-05-15 | October 2023 | | MySQL 5.7 is being deprecated in October 2023 and Grafana's policy is to test against the officially supported version. | Planned |

View File

@@ -6,7 +6,13 @@
# [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.
#
# ## 5.2.0 (2024-01-18)
#
# ### Changed
#
# - Updated `make vale` to use latest Vale style and configuration.
# - Updated `make vale` to use platform appropriate image.
#
# ## 5.1.2 (2023-11-08)
#
# ### Added
@@ -704,14 +710,14 @@ case "${image}" in
"${PODMAN}" run \
--init \
--interactive \
--platform linux/amd64 \
--rm \
--workdir /etc/vale \
--tty \
${volumes} \
"${DOCS_IMAGE}" \
"--minAlertLevel=${VALE_MINALERTLEVEL}" \
--config=/etc/vale/.vale.ini \
--output=line \
'--glob=*.md' \
--output=/etc/vale/rdjsonl.tmpl \
/hugo/content/docs | sed "s#$(proj_dst "${proj}")#sources#"
;;
*)

View File

@@ -42,6 +42,10 @@ title: Grafana open source documentation
<img src="/static/img/logos/logo-docker.svg">
<h5>Run Docker image</h5>
</a>
<a href="{{< relref "setup-grafana/installation/kubernetes/" >}}" class="nav-cards__item nav-cards__item--install">
<img src="/static/img/logos/logo-kubernetes.svg">
<h5>Run on Kubernetes</h5>
</a>
<a href="https://grafana.com/docs/grafana-cloud/" class="nav-cards__item nav-cards__item--install">
<div class="nav-cards__icon fa fa-cloud">
</div>
@@ -77,8 +81,8 @@ title: Grafana open source documentation
<h4>Provisioning</h4>
<p>Learn how to automate your Grafana configuration.</p>
</a>
<a href="{{< relref "whatsnew/whats-new-in-v10-2/" >}}" class="nav-cards__item nav-cards__item--guide">
<h4>What's new in v10.2</h4>
<a href="{{< relref "whatsnew/whats-new-in-v10-3/" >}}" class="nav-cards__item nav-cards__item--guide">
<h4>What's new in v10.3</h4>
<p>Explore the features and enhancements in the latest release.</p>
</a>

View File

@@ -71,6 +71,7 @@ Define a query to get the data you want to measure and a condition that needs to
All alert rules are managed by Grafana by default. If you want to switch to a data source-managed alert rule, click **Switch to data source-managed alert rule**.
1. Add one or more [expressions][expression-queries].
a. For each expression, select either **Classic condition** to create a single alert rule, or choose from the **Math**, **Reduce**, and **Resample** options to generate separate alert for each series.
{{% admonition type="note" %}}
@@ -79,6 +80,14 @@ Define a query to get the data you want to measure and a condition that needs to
b. Click **Preview** to verify that the expression is successful.
{{% admonition type="note" %}}
The recovery threshold feature is currently only available in OSS.
{{% /admonition %}}
1. To add a recovery threshold, turn the **Custom recovery threshold** toggle on and fill in a value for when your alert rule should stop firing.
You can only add one recovery threshold in a query and it must be the alert condition.
1. Click **Set as alert condition** on the query or expression you want to set as your alert condition.
## Set alert evaluation behavior

View File

@@ -128,6 +128,26 @@ When the queried data satisfies the defined condition, Grafana triggers the asso
By default, the last expression added is used as the alert condition.
## Recovery threshold
{{% admonition type="note" %}}
The recovery threshold feature is currently only available in OSS.
{{% /admonition %}}
To reduce the noise of flapping alerts, you can set a recovery threshold different to the alert threshold.
Flapping alerts occur when a metric hovers around the alert threshold condition and may lead to frequent state changes, resulting in too many notifications being generated.
Grafana-managed alert rules are evaluated for a specific interval of time. During each evaluation, the result of the query is checked against the threshold set in the alert rule. If the value of a metric is above the threshold, an alert rule fires and a notification is sent. When the value goes below the threshold and there is an active alert for this metric, the alert is resolved, and another notification is sent.
It can be tricky to create an alert rule for a noisy metric. That is, when the value of a metric continually goes above and below a threshold. This is called flapping and results in a series of firing - resolved - firing notifications and a noisy alert state history.
For example, if you have an alert for latency with a threshold of 1000ms and the number fluctuates around 1000 (say 980 ->1010 -> 990 -> 1020, and so on) then each of those will trigger a notification.
To solve this problem, you can set a (custom) recovery threshold, which basically means having two thresholds instead of one. An alert is triggered when the first threshold is crossed and is resolved only when the second threshold is crossed.
For example, you could set a threshold of 1000ms and a recovery threshold of 900ms. This way, an alert rule will only stop firing when it goes under 900ms and flapping is reduced.
{{% docs/reference %}}
[data-source-alerting]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/alerting/fundamentals/data-source-alerting"
[data-source-alerting]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/alerting-and-irm/alerting/fundamentals/data-source-alerting"

View File

@@ -22,9 +22,11 @@ To do this, you need to make sure that your alert rule is in the right evaluatio
## Evaluation group
Every alert rule is part of an evaluation group. Each evaluation group contains an evaluation interval that determines how frequently the alert rule is checked. Alert rules within the same group are evaluated one after the other, while alert rules in different groups can be evaluated simultaneously.
Every alert rule is part of an evaluation group. Each evaluation group contains an evaluation interval that determines how frequently the alert rule is checked.
This feature is especially useful for Prometheus/Mimir rules when you want to ensure that recording rules are evaluated before any alert rules.
**Data-source managed** alert rules within the same group are evaluated one after the other, while alert rules in different groups can be evaluated simultaneously. This feature is especially useful when you want to ensure that recording rules are evaluated before any alert rules.
**Grafana-managed** alert rules are evaluated at the same time, regardless of alert rule group. The default evaluation interval is set at 10 seconds, which means that Grafana-managed alert rules are evaluated every 10 seconds to the closest 10-second window on the clock, for example, 10:00:00, 10:00:10, 10:00:20, and so on. You can also configure your own evaluation interval, if required.
**Note:**

View File

@@ -26,13 +26,13 @@ In the Contact points tab, you can see a list of your contact points.
**Note:** You can edit an existing contact by clicking the Edit icon.
2. Execute a template from one or more fields such as Message and Subject:
1. Execute a template from one or more fields such as Message and Subject:
{{< figure max-width="940px" src="/static/img/docs/alerting/unified/use-notification-template-9-4.png" caption="Use notification template" >}}
For more information on how to write and execute templates, refer to [Using Go's templating language][using-go-templating-language] and [Create notification templates][create-notification-templates].
3. Click Save template.
1. Click **Save contact point**.
{{% docs/reference %}}
[create-notification-templates]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/alerting/manage-notifications/template-notifications/create-notification-templates"

View File

@@ -2,7 +2,7 @@
aliases:
- ../provision-alerting-resources/
canonical: https://grafana.com/docs/grafana/latest/alerting/set-up/provision-alerting-resources/
description: Provision alerting resources
description: Import and export alerting resources
keywords:
- grafana
- alerting
@@ -14,23 +14,23 @@ labels:
- cloud
- enterprise
- oss
title: Provision Grafana Alerting resources
title: Import and export Grafana Alerting resources
weight: 300
---
# Provision Grafana Alerting resources
# Import and export Grafana Alerting resources
Alerting infrastructure is often complex, with many pieces of the pipeline that often live in different places. Scaling this across multiple teams and organizations is an especially challenging task. Grafana Alerting provisioning makes this process easier by enabling you to create, manage, and maintain your alerting data in a way that best suits your organization.
Alerting infrastructure is often complex, with many pieces of the pipeline that often live in different places. Scaling this across multiple teams and organizations is an especially challenging task. Importing and exporting (or provisioning) your alerting resources in Grafana Alerting makes this process easier by enabling you to create, manage, and maintain your alerting data in a way that best suits your organization.
Provisioning for Grafana Alerting supports alert rules, contact points, notification policies, mute timings, and templates.
You can import alert rules, contact points, notification policies, mute timings, and templates.
You cannot edit provisioned alerting resources in the Grafana UI in the same way as unprovisioned alerting resources. You can only edit provisioned contact points, notification policies, templates, and mute timings in the source where they were created. For example, if you provision your alerting resources using files from disk, you cannot edit the data in Terraform or from within Grafana.
You cannot edit imported alerting resources in the Grafana UI in the same way as alerting resources that were not imported. You can only edit imported contact points, notification policies, templates, and mute timings in the source where they were created. For example, if you manage your alerting resources using files from disk, you cannot edit the data in Terraform or from within Grafana.
To modify provisioned alert rules, you can use the **Modify export** feature to edit and then export.
To modify imported alert rules, you can use the **Modify export** feature to edit and then export.
Choose from the options below to provision your Grafana Alerting resources.
Choose from the options below to import your Grafana Alerting resources.
1. Use file provisioning to provision your Grafana Alerting resources, such as alert rules and contact points, through files on disk.
1. Use file provisioning to manage your Grafana Alerting resources, such as alert rules and contact points, through files on disk.
{{% admonition type="note" %}}
File provisioning is not available in Grafana Cloud instances.

View File

@@ -14,13 +14,13 @@ labels:
- cloud
- enterprise
- oss
title: Create and manage alerting resources using file provisioning
title: Use file provisioning to manage alerting resources
weight: 100
---
## Create and manage alerting resources using file provisioning
## Use file provisioning to manage alerting resources
Provision your alerting resources using files from disk. When you start Grafana, the data from these files is created in your Grafana system. Grafana adds any new resources you created, updates any that you changed, and deletes old ones.
Manage your alerting resources using files from disk. When you start Grafana, the data from these files is created in your Grafana system. Grafana adds any new resources you created, updates any that you changed, and deletes old ones.
Arrange your files in a directory in a way that best suits your use case. For example, you can choose a team-based layout where every team has its own file, you can have one big file for all your teams; or you can have one file per resource type.
@@ -28,9 +28,9 @@ Details on how to set up the files and which fields are required for each object
**Note:**
Provisioning takes place during the initial set up of your Grafana system, but you can re-run it at any time using the [Grafana Admin API][reload-provisioning-configurations].
Importing takes place during the initial set up of your Grafana system, but you can re-run it at any time using the [Grafana Admin API][reload-provisioning-configurations].
### Provision alert rules
### Import alert rules
Create or delete alert rules in your Grafana instance(s).
@@ -41,11 +41,11 @@ Create or delete alert rules in your Grafana instance(s).
Example configuration files can be found below.
1. Ensure that your files are in the right directory on the node running the Grafana server, so that they deploy alongside your Grafana instance(s).
1. Delete the alert rules in Grafana that will be provisioned.
1. Delete the alert rules in Grafana that are going to be imported.
**Note:**
If you do not delete the alert rule, it will clash with the provisioned alert rule once uploaded.
If you do not delete the alert rule, it will clash with the imported alert rule once uploaded.
Here is an example of a configuration file for creating alert rules.
@@ -133,7 +133,7 @@ deleteRules:
uid: my_id_1
```
### Provision contact points
### Import contact points
Create or delete contact points in your Grafana instance(s).
@@ -492,7 +492,7 @@ settings:
{{ template "default.title" . }}
```
### Provision notification policies
### Import notification policies
Create or reset the notification policy tree in your Grafana instance(s).
@@ -584,7 +584,7 @@ In Grafana, the entire notification policy tree is considered a single, large re
Since the policy tree is a single resource, applying it will overwrite a policy tree created through any other means.
### Provision templates
### Import templates
Create or delete templates in your Grafana instance(s).
@@ -603,7 +603,7 @@ apiVersion: 1
# List of templates to import or update
templates:
# <int> organization ID, default = 1
- orgID: 1
- orgId: 1
# <string, required> name of the template, must be unique
name: my_first_template
# <string, required> content of the the template
@@ -624,7 +624,7 @@ deleteTemplates:
name: my_first_template
```
### Provision mute timings
### Import mute timings
Create or delete mute timings in your Grafana instance(s).

View File

@@ -13,11 +13,11 @@ labels:
products:
- enterprise
- oss
title: Create and manage alerting resources using Terraform
title: Use Terraform to manage alerting resources
weight: 200
---
# Create and manage alerting resources using Terraform
# Use Terraform to manage alerting resources
Use Terraforms Grafana Provider to manage your alerting resources and provision them into your Grafana system. Terraform provider support for Grafana Alerting makes it easy to create, manage, and maintain your entire Grafana Alerting stack as code.

View File

@@ -13,12 +13,12 @@ labels:
- cloud
- enterprise
- oss
menuTitle: Manage provisioned resources in Grafana
title: Manage provisioned alerting resources in Grafana
menuTitle: Manage provisioned alerting resources
title: Manage provisioned alerting resources
weight: 300
---
# Manage provisioned alerting resources in Grafana
# Manage provisioned alerting resources
Verify that your alerting resources were created in Grafana, as well as edit or export your provisioned alerting resources.

View File

@@ -0,0 +1,77 @@
---
description: Breaking changes for Grafana v10.3
keywords:
- grafana
- breaking changes
- documentation
- '10.3'
- '10.2.3'
- release notes
labels:
products:
- cloud
- enterprise
- oss
title: Breaking changes in Grafana v10.3
weight: -2
---
# Breaking changes in Grafana v10.3
Following are breaking changes that you should be aware of when upgrading to Grafana v10.3. Breaking changes that were introduced in release 10.2.3 are also included here and are marked with an asterisk.
For our purposes, a breaking change is any change that requires users or operators to do something. This includes:
- Changes in one part of the system that could cause other components to fail
- Deprecations or removal of a feature
- Changes to an API that could break automation
- Changes that affect some plugins or functions of Grafana
- Migrations that cant be rolled back
For each change, the provided information:
- Helps you determine if youre affected
- Describes the change or relevant background information
- Guides you in how to mitigate for the change or migrate
- Provides more learning resources
For release highlights and deprecations, refer to our [v10.3 Whats new](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/whatsnew/whats-new-in-v10-3/). For the specific steps we recommend when you upgrade to v10.3, check out our [Upgrade guide](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/upgrade-guide/upgrade-v10.3/).
<!--
## Feature
You must use relative references when linking to docs within the Grafana repo. Please do not use absolute URLs. For more information about relrefs, refer to [Links and references](/docs/writers-toolkit/writing-guide/references/).-->
## General breaking changes
### Transformations\*
In panels using the extract fields transformation, where one of the extracted names collides with one of the already existing fields, the extracted field will be renamed. Issue [#77569](https://github.com/grafana/grafana/issues/77569).
If you use the Table visualization, you might see some inconsistencies in your panels. We have updated the table column naming. This will potentially affect field transformations and/or field overrides. To resolve this, either:
- Update the transformation you are using
- Update field override. Issue [#76899](https://github.com/grafana/grafana/issues/76899).
Users who have transformations with the Time field might see their transformations are not working. Those panels that have broken transformations will fail to render. This is because we changed the field key. See related PR: [#69865](https://github.com/grafana/grafana/pull/69865). To resolve this, either:
- Remove the affected panel and re-create it
- Select the Time field again
- Edit the time field as Time for transformation in panel.json or dashboard.json. Issue [#76641](https://github.com/grafana/grafana/issues/76641).
### Data source permissions\*
The following data source permission endpoints have been removed:
- `GET /datasources/:datasourceId/permissions`
- `POST /api/datasources/:datasourceId/permissions`
- `DELETE /datasources/:datasourceId/permissions`
- `POST /datasources/:datasourceId/enable-permissions`
- `POST /datasources/:datasourceId/disable-permissions`
Please use the following endpoints instead:
- `GET /api/access-control/datasources/:uid` for listing data source permissions
- `POST /api/access-control/datasources/:uid/users/:id`, `POST /api/access-control/datasources/:uid/teams/:id`, and `POST /api/access-control/datasources/:uid/buildInRoles/:id` for adding or removing data source permissions
If you are using the Grafana provider for Terraform to manage data source permissions, you will need to upgrade your provider to [version 2.6.0](https://registry.terraform.io/providers/grafana/grafana/2.6.0/docs) or newer to ensure that data source permission provisioning keeps working. Issue [#5880](https://github.com/grafana/grafana-enterprise/pull/5880).

View File

@@ -44,7 +44,10 @@ Annotations are supported for the following visualization types:
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)
To add annotations directly in the panel:
- The dashboard must already be saved.
- The built-in query must be enabled. Learn more in [Built-in query](#built-in-query).
### Add an annotation

View File

@@ -14,7 +14,7 @@ labels:
- oss
menuTitle: Best practices
title: Grafana dashboard best practices
weight: 100
weight: 800
---
# Grafana dashboard best practices

View File

@@ -0,0 +1,60 @@
---
aliases:
- ../../reference/export_import/ # /docs/grafana/<GRAFANA_VERSION>/reference/export_import/
- ../export-import/ # /docs/grafana/<GRAFANA_VERSION>/dashboards/export-import/
canonical: https://grafana.com/docs/grafana/latest/dashboards/build-dashboards/import-dashboards/
keywords:
- grafana
- dashboard
- import
labels:
products:
- cloud
- enterprise
- oss
menuTitle: Import dashboards
title: Import dashboards
description: Learn how to import dashboards and about Grafana's preconfigured dashboards
weight: 5
---
# Import dashboards
You can import preconfigured dashboards into your Grafana instance or Cloud stack using the UI or the [HTTP API][].
## Import a dashboard
To import a dashboard, follow these steps:
1. Click **Dashboards** in the primary menu.
1. Click **New** and select **Import** in the drop-down menu.
1. Perform one of the following steps:
- Upload a dashboard JSON file.
- Paste a [Grafana.com dashboard](#discover-dashboards-on-grafanacom) URL or ID into the field provided.
- Paste dashboard JSON text directly into the text area.
1. (Optional) Change the dashboard name, folder, or UID, and specify metric prefixes, if the dashboard uses any.
1. Select a data source, if required.
1. Click **Import**.
1. Save the dashboard.
## Discover dashboards on grafana.com
The [Dashboards page](https://grafana.com/grafana/dashboards/) on grafana.com provides you with dashboards for common server applications. Browse our library of official and community-built dashboards and import them to quickly get up and running.
{{< figure src="/media/docs/grafana/dashboards/screenshot-gcom-dashboards.png" alt="Preconfigured dashboards on grafana.com">}}
You can also add to this library by exporting one of your own dashboards. For more information, refer to [Share dashboards and panels][].
## More examples
Your Grafana Cloud stack comes with several default dashboards in the **Grafana Cloud** folder in **Dashboards**. If you're running your own installation of Grafana, you can find more example dashboards in the `public/dashboards/` directory.
{{% docs/reference %}}
[HTTP API]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/developers/http_api"
[HTTP API]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/developer-resources/api-reference/http-api"
[Share dashboards and panels]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/dashboards/share-dashboards-panels"
[Share dashboards and panels]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/dashboards/share-dashboards-panels"
{{% /docs/reference %}}

View File

@@ -107,10 +107,16 @@ You can include dynamic dashboards with panels or rows, set to repeat by a varia
By default, reports use the saved time range of the dashboard. You can change the time range of the report by:
- Saving a modified time range to the dashboard.
- Saving a modified time range to the dashboard. Changing the dashboard time range without saving it doesn't change the time zone of the report.
- Setting a time range via the **Time range** field in the report form. If specified, the custom time range overrides the time range from the report's dashboard.
The page header of the report displays the time range for the dashboard's data queries. Dashboards set to use the browser's time zone use the time zone on the Grafana server.
The page header of the report displays the time range for the dashboard's data queries.
#### Report time zones
Reports use the time zone of the dashboard from which theyre generated. You can control the time zone for your reports by setting the dashboard to a specific time zone. Note that this affects the display of the dashboard for all users.
If a dashboard has the **Browser Time** setting, the reports generated from that dashboard use the time zone of the Grafana server. As a result, this time zone might not match the time zone of users creating or receiving the report.
If the time zone is set differently between your Grafana server and its remote image renderer, then the time ranges in the report might be different between the page header and the time axes in the panels. To avoid this, set the time zone to UTC for dashboards when using a remote renderer. Each dashboard's time zone setting is visible in the [time range controls][].

View File

@@ -3,23 +3,15 @@ aliases:
- ../features/dashboard/dashboards/
- ../panels/working-with-panels/organize-dashboard/
- ../reference/dashboard_folders/
- ../reference/export_import/
- ../reference/timerange/
- ../troubleshooting/troubleshoot-dashboards/
- dashboard-folders/
- dashboard-manage/
- export-import/
canonical: https://grafana.com/docs/grafana/latest/dashboards/manage-dashboards/
keywords:
- grafana
- dashboard
- dashboard folders
- folder
- folders
- import
- export
- troubleshoot
- time range
- scripting
labels:
products:
- cloud
@@ -27,34 +19,31 @@ labels:
- oss
menuTitle: Manage dashboards
title: Manage dashboards
description: Learn about dashboard folders, generative AI features for dashboards, and troubleshooting
description: Learn about dashboard management and generative AI features for dashboards
weight: 8
---
# Manage dashboards
This topic includes techniques you can use to manage your Grafana dashboards, including:
On the **Dashboards** page, you can perform dashboard management tasks such as:
- [Creating and managing dashboard folders](#create-and-manage-dashboard-folders)
- [Exporting and importing dashboards](#export-and-import-dashboards)
- [Organizing dashboards](#organize-a-dashboard)
- [Troubleshooting dashboards](#troubleshoot-dashboards)
- [Browsing](#browse-dashboards) and [creating](#create-a-dashboard-folder) dashboard folders
- [Managing folder permissions](#folder-permissions)
- [Adding generative AI features to dashboards](#set-up-generative-ai-features-for-dashboards)
For more information about creating dashboards, refer to [Add and organize panels](../add-organize-panels).
For more information about creating dashboards, refer to [Build dashboards][].
## Browse dashboards
On the **Dashboards** page, you can browse and manage folders and dashboards. This includes the options to:
- Create folders and dashboards
- Create folders and dashboards.
- Move dashboards between folders.
- Delete multiple dashboards and folders.
- Navigate to a folder.
- Manage folder permissions. For more information, refer to [Dashboard permissions][].
{{% admonition type="note" %}}
As of Grafana 10.2, there is no longer a special **General** folder. Dashboards without a folder are now shown at the top level alongside folders.
{{% /admonition %}}
The page lists all the dashboards to which you have access, grouped into folders. Dashboards without a folder are displayed at the top level alongside folders.
## Create a dashboard folder
@@ -76,9 +65,9 @@ Alerts can't be placed in folders with slashes (\ /) in the name. If you wish to
**To edit the name of a folder:**
1. Click **Dashboards** in the main menu.
1. Click **Dashboards** in the primary menu.
1. Navigate to the folder by selecting it in the list, or searching for it.
1. Click the pencil icon labelled **Edit title** in the header and update the name of the folder.
1. Click the **Edit title** icon (pencil) in the header and update the name of the folder.
The new folder name is automatically saved.
@@ -88,7 +77,7 @@ You can assign permissions to a folder. Dashboards in the folder inherit any per
**To modify permissions for a folder:**
1. Click **Dashboards** in the main menu.
1. Click **Dashboards** in the primary menu.
1. Navigate to the folder by selecting it in the list, or searching for it.
1. On the folder's page, click **Folder actions** and select **Manage permissions** in the drop-down.
1. Update the permissions as desired.
@@ -97,49 +86,6 @@ Changes are saved automatically.
For more information about dashboard permissions, refer to [Dashboard permissions][].
## Export and import dashboards
You can use the Grafana UI or the [HTTP API][] to export and import dashboards.
### Export a dashboard
The dashboard export action creates a Grafana JSON file that contains everything you need, including layout, variables, styles, data sources, queries, and so on, so that you can later import the dashboard.
1. Click **Dashboards** in the main menu.
1. Open the dashboard you want to export.
1. Click the **Share** icon in the top navigation bar.
1. Click **Export**.
If you're exporting the dashboard to use in another instance, with different data source UIDs, enable the **Export for sharing externally** switch.
1. Click **Save to file**.
Grafana downloads a JSON file to your local machine.
#### Make a dashboard portable
If you want to export a dashboard for others to use, you can add template variables for things like a metric prefix (use a constant variable) and server name.
A template variable of the type `Constant` is automatically hidden in the dashboard, and is also added as a required input when the dashboard is imported.
### Import a dashboard
1. Click **Dashboards** in the left-side menu.
1. Click **New** and select **Import** in the dropdown menu.
1. Perform one of the following steps:
- Upload a dashboard JSON file
- Paste a [Grafana.com](https://grafana.com) dashboard URL
- Paste dashboard JSON text directly into the text area
The import process enables you to change the name of the dashboard, pick the data source you want the dashboard to use, and specify any metric prefixes (if the dashboard uses any).
### Discover dashboards on grafana.com
Find dashboards for common server applications at [Grafana.com/dashboards](https://grafana.com/dashboards).
{{< figure src="/media/docs/grafana/dashboards/screenshot-gcom-dashboards.png" alt="Preconfigured dashboards on grafana.com">}}
## Set up generative AI features for dashboards
{{< docs/public-preview product="Generative AI in dashboards" featureFlag="`dashgpt`" >}}
@@ -153,56 +99,13 @@ To access these features, enable the `dashgpt` feature toggle. Then install and
When enabled, the **✨ Auto generate** option displays next to the **Title** and **Description** fields in your panels and dashboards, or when you press the **Save** button.
## Troubleshoot dashboards
This section provides information to help you solve common dashboard problems.
### Dashboard is slow
- Are you trying to render dozens (or hundreds or thousands) of time-series on a graph? This can cause the browser to lag. Try using functions like `highestMax` (in Graphite) to reduce the returned series.
- Sometimes the series names can be very large. This causes larger response sizes. Try using `alias` to reduce the size of the returned series names.
- Are you querying many time-series or for a long range of time? Both of these conditions can cause Grafana or your data source to pull in a lot of data, which may slow it down.
- It could be high load on your network infrastructure. If the slowness isn't consistent, this may be the problem.
### Dashboard refresh rate issues
By default, Grafana queries your data source every 30 seconds. Setting a low refresh rate on your dashboards puts unnecessary stress on the backend. In many cases, querying this frequently isn't necessary because the data isn't being sent to the system such that changes would be seen.
We recommend the following:
- Only enable auto-refreshing on dashboards, panels, or variables unless if necessary. Users can refresh their browser manually, or you can set the refresh rate for a time period that makes sense (every ten minutes, every hour, and so on).
- If it's required, then set the refresh rate to once a minute. Users can always refresh the dashboard manually.
- If your dashboard has a longer time period (such as a week), then you really don't need automated refreshing.
#### Handling or rendering null data is wrong or confusing
Some applications publish data intermittently; for example, they only post a metric when an event occurs. By default, Grafana graphs connect lines between the data points. This can be very deceiving.
In the picture below we've enabled:
- Points and 3-point radius to highlight where data points are actually present.
- **Connect null values\* is set to **Always\*\*.
{{< figure src="/static/img/docs/troubleshooting/grafana_null_connected.png" max-width="1200px" alt="Graph with null values connected" >}}
In this graph, we set graph to show bars instead of lines and set the **No value** under **Standard options** to **0**. There is a very big difference in the visuals.
{{< figure src="/static/img/docs/troubleshooting/grafana_null_zero.png" max-width="1200px" alt="Graph with null values not connected" >}}
### More examples
You can find more examples in `public/dashboards/` directory of your Grafana installation.
{{% docs/reference %}}
[Dashboard permissions]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/administration/roles-and-permissions#dashboard-permissions"
[Dashboard permissions]: "/docs/grafana-cloud/ -> /docs/grafana/<GRAFANA VERSION>/administration/roles-and-permissions#dashboard-permissions"
[panels]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations"
[panels]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations"
[Grafana LLM plugin documentation]: "/docs/grafana/ -> /docs/grafana-cloud/alerting-and-irm/machine-learning/configure/llm-plugin"
[Grafana LLM plugin documentation]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/alerting-and-irm/machine-learning/configure/llm-plugin"
[HTTP API]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/developers/http_api"
[HTTP API]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/developer-resources/api-reference/http-api"
[Grafana LLM plugin documentation]: "/docs/grafana/ -> /docs/grafana-cloud/alerting-and-irm/machine-learning/llm-plugin"
[Grafana LLM plugin documentation]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/alerting-and-irm/machine-learning/llm-plugin"
[Build dashboards]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/dashboards/build-dashboards"
[Build dashboards]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/dashboards/build-dashboards"
{{% /docs/reference %}}

View File

@@ -0,0 +1,58 @@
---
aliases:
- ../troubleshooting/troubleshoot-dashboards/
- ../reference/timerange/
canonical: https://grafana.com/docs/grafana/latest/dashboards/troubleshoot-dashboards/
keywords:
- grafana
- dashboard
- troubleshoot
- time range
labels:
products:
- cloud
- enterprise
- oss
menuTitle: Troubleshoot dashboards
title: Troubleshoot dashboards
description: Learn how to troubleshoot common dashboard issues
weight: 300
---
# Troubleshoot dashboards
Use the following strategies to help you troubleshoot common dashboard problems.
## Dashboard is slow
- Are you trying to render dozens (or hundreds or thousands) of time series on a graph? This can cause the browser to lag. Try using functions like `highestMax` (in Graphite) to reduce the number of returned series.
- Sometimes series names can be very large. This causes larger response sizes. Try using `alias` to reduce the size of the returned series names.
- Are you querying many time series or a long time range? Both of these conditions can cause Grafana or your data source to pull in a lot of data, which may slow the dashboard down. Try reducing one or both of these.
- There could be high load on your network infrastructure. If the slowness isn't consistent, this may be the problem.
## Dashboard refresh rate issues
By default, Grafana queries your data source every 30 seconds. However, setting a low refresh rate on your dashboards puts unnecessary stress on the backend. In many cases, querying this frequently isn't necessary because the data source isn't sending data often enough for there to be changes every 30 seconds.
We recommend the following:
- Only enable auto-refreshing on dashboards, panels, or variables if necessary. Users can refresh their browser manually.
- If you require auto-refreshing, then set the refresh rate to a longer time period that makes sense, such as once a minute, every 10 minutes, or every hour.
- Check the time range of your dashboard. If your dashboard has a longer time range, such as a week, then you really don't need automated refreshing and you should disable it.
## Handling or rendering null data is wrong or confusing
Some applications publish data intermittently; for example, they only post a metric when an event occurs. By default, Grafana graphs connect lines between the data points, but this can be deceptive.
The graph in the following image has:
- Points and 3-point radius enabled to highlight where data points are actually present.
- **Connect null values** set to **Always**.
{{< figure src="/static/img/docs/troubleshooting/grafana_null_connected.png" max-width="1200px" alt="Graph with null values connected" >}}
The graph in this next image shows bars instead of lines and has the **No value** option under **Standard options** set to **0**.
{{< figure src="/static/img/docs/troubleshooting/grafana_null_zero.png" max-width="1200px" alt="Graph with null values not connected" >}}
As you can see, there's a significant difference in the visualizations.

View File

@@ -60,6 +60,7 @@ datasources:
access: proxy
url: http://localhost:3100
jsonData:
timeout: 60
maxLines: 1000
```

View File

@@ -19,7 +19,7 @@ weight: 1300
# Prometheus data source
Prometheus is an open-source database that uses an telemetry collector agent to scrape and store metrics used for monitoring and alerting. If you are just getting started with Prometheus, see [What is Prometheus?][intro-to-prometheus].
Prometheus is an open-source database that uses a telemetry collector agent to scrape and store metrics used for monitoring and alerting. If you are just getting started with Prometheus, see [What is Prometheus?][intro-to-prometheus].
Grafana provides native support for Prometheus.
For instructions on downloading Prometheus see [Get started with Grafana and Prometheus][get-started-prometheus].

View File

@@ -20,11 +20,11 @@ weight: 1400
# Tempo data source
Grafana ships with built-in support for [Tempo](https://grafana.com/docs/tempo/latest/), a high-volume, minimal-dependency trace storage, open-source tracing solution from Grafana Labs. This topic explains configuration and queries specific to the Tempo data source.
Grafana ships with built-in support for [Tempo](https://grafana.com/docs/tempo/latest/), a high-volume, minimal-dependency trace storage, open source tracing solution from Grafana Labs. This topic explains configuration and queries specific to the Tempo data source.
For instructions on how to add a data source to Grafana, refer to the [administration documentation][data-source-management].
Only users with the organization administrator role can add data sources.
Administrators can also [configure the data source via YAML](#provision-the-data-source) with Grafana's provisioning system.
Administrators can also [configure the data source via YAML][configure-tempo-data-source] with Grafana's provisioning system.
Once you've added the data source, you can [configure it]({{< relref "./configure-tempo-data-source/" >}}) so that your Grafana instance's users can create queries in its [query editor]({{< relref "./query-editor/" >}}) when they [build dashboards][build-dashboards] and use [Explore][explore].
@@ -37,6 +37,9 @@ Once you've added the data source, you can [configure it]({{< relref "./configur
[configure-grafana-feature-toggles]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/setup-grafana/configure-grafana#feature_toggles"
[configure-grafana-feature-toggles]: "/docs/grafana-cloud/ -> /docs/grafana/<GRAFANA VERSION>/setup-grafana/configure-grafana#feature_toggles"
[configure-tempo-data-source]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/datasources/tempo/configure-tempo-data-source#provision-the-data-source"
[configure-tempo-data-source]: "/docs/grafana-cloud/ -> docs/grafana-cloud/connect-externally-hosted/data-sources/tempo/configure-tempo-data-source#provision-the-data-source"
[data-source-management]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/administration/data-source-management"
[data-source-management]: "/docs/grafana-cloud/ -> /docs/grafana/<GRAFANA VERSION>/administration/data-source-management"

View File

@@ -55,7 +55,7 @@ There are two ways to configure the trace to logs feature:
You can also click **Open advanced data source picker** to see more options, including adding a data source.
1. Set start and end time shift. As the logs timestamps may not exactly match the timestamps of the spans in trace it may be necessary to search in larger or shifted time range to find the desired logs.
1. Select which tags to use in the logs query. The tags you configure must be present in the spans attributes or resources for a trace to logs span link to appear. You can optionally configure a new name for the tag. This is useful for example if the tag has dots in the name and the target data source does not allow using dots in labels. In that case you can for example remap `http.status` to `http_status`.
1. Select which tags to use in the logs query. The tags you configure must be present in the span's attributes or resources for a trace to logs span link to appear. You can optionally configure a new name for the tag. This is useful, for example, if the tag has dots in the name and the target data source does not allow using dots in labels. In that case, you can for example remap `http.status` (the span attribute) to `http_status` (the data source field). "Data source" in this context can refer to Loki, or another log data source.
1. Optionally switch on the **Filter by trace ID** and/or **Filter by span ID** setting to further filter the logs if your logs consistently contain trace or span IDs.
### Configure a custom query

View File

@@ -26,13 +26,37 @@ weight: 80
# Configure data links
You can use data link variables or data links to create links between panels.
Data links allow you to provide more granular context to your links. You can create links that include the series name or even the value under the cursor. For example, if your visualization shows four servers, you can add a data link to one or two of them. You can also link panels using data links.
The link itself is accessible in different ways depending on the visualization. For the time series visualization you need to click a data point or line:
![Time series visualization with a data link displayed](/media/docs/grafana/panels-visualizations/screenshot-time-series-data-link-v10.3.png)
For visualizations like stat, gauge, or bar gauge you can click anywhere on the visualization to open the context menu:
![Stat visualization with a data link displayed](/media/docs/grafana/panels-visualizations/screenshot-stat-data-link-v10.3.png)
If there's only one data link in the visualization, clicking anywhere on the visualization opens the link rather than the context menu.
## Supported visualizations
You can configure data links for the following visualizations:
| | | |
| -------------------------- | ---------------------- | -------------------------------- |
| [Bar chart][bar chart] | [Geomap][geomap] | [State timeline][state timeline] |
| [Bar gauge][bar gauge] | [Heatmap][heatmap] | [Status history][status history] |
| [Candlestick][candlestick] | [Histogram][histogram] | [Table][table] |
| [Canvas][canvas] | [Pie chart][pie chart] | [Time series][time series] |
| [Gauge][gauge] | [Stat][stat] | [Trend][trend] |
<!--Also xy chart -->
## Data link variables
You can use variables in data links to refer to series fields, labels, and values. For more information about data links, refer to [Data links](#data-links).
Variables in data links let you send people to a detailed dashboard with preserved data filters. For example, you could use variables to specify a label, time range, series, or variable selection.
To see a list of available variables, type `$` in the data link **URL** field to see a list of variables that you can use.
To see a list of available variables, enter `$` in the data link **URL** field.
{{% admonition type="note" %}}
These variables changed in 6.4 so if you have an older version of Grafana, then use the version picker to select docs for an older version of Grafana.
@@ -40,50 +64,61 @@ These variables changed in 6.4 so if you have an older version of Grafana, then
Azure Monitor, [CloudWatch][], and [Google Cloud Monitoring][] have pre-configured data links called _deep links_.
You can also use template variables in your data links URLs, refer to [Templates and variables][] for more information on template variables.
You can also use template variables in your data links URLs. For more information, refer to [Templates and variables][].
## Time range panel variables
### Time range panel variables
These variables allow you to include the current time range in the data link URL.
These variables allow you to include the current time range in the data link URL:
- `__url_time_range` - current dashboard's time range (i.e. `?from=now-6h&to=now`)
- `$__from and $__to` - For more information, refer to [Global variables][].
| Variable | Description |
| ------------------ | ------------------------------------------------------------------- |
| `__url_time_range` | Current dashboard's time range (for example, `?from=now-6h&to=now`) |
| `__from` | For more information, refer to [Global variables][]. |
| `__to` | For more information, refer to [Global variables][]. |
## Series variables
### Series variables
Series-specific variables are available under `__series` namespace:
- `__series.name` - series name to the URL
| Variable | Description |
| --------------- | ---------------------- |
| `__series.name` | Series name to the URL |
## Field variables
### Field variables
Field-specific variables are available under `__field` namespace:
- `__field.name` - the name of the field
- `__field.labels.<LABEL>` - label's value to the URL. If your label contains dots, then use `__field.labels["<LABEL>"]` syntax.
| Variable | Description |
| ------------------------ | --------------------------------------------------------------------------------------------------- |
| `__field.name` | The name of the field |
| `__field.labels.<LABEL>` | Label's value to the URL. If your label contains dots, then use `__field.labels["<LABEL>"]` syntax. |
## Value variables
### Value variables
Value-specific variables are available under `__value` namespace:
- `__value.time` - value's timestamp (Unix ms epoch) to the URL (i.e. `?time=1560268814105`)
- `__value.raw` - raw value
- `__value.numeric` - numeric representation of a value
- `__value.text` - text representation of a value
- `__value.calc` - calculation name if the value is result of calculation
| Variable | Description |
| ----------------- | --------------------------------------------------------------------------------- |
| `__value.time` | Value's timestamp (Unix ms epoch) to the URL (for example, `?time=1560268814105`) |
| `__value.raw` | Raw value |
| `__value.numeric` | Numeric representation of a value |
| `__value.text` | Text representation of a value |
| `__value.calc` | Calculation name if the value is result of calculation |
Using value-specific variables in data links can show different results depending on the set option of Tooltip mode.
## Data variables
### Data variables
To access values and labels from other fields use:
- `${__data.fields[i]}` - value of field `i` (on the same row)
- `${__data.fields["NameOfField"]}` - value of field using name instead of index
- `${__data.fields["NameOfField"]}` - value of field using name instead of index
- `${__data.fields[1].labels.cluster}` - access labels of another field
| Variable | Description |
| --------------------------------- | ------------------------------------------ |
| `__data.fields[i]` | Value of field `i` (on the same row) |
| `__data.fields["NameOfField"]` | Value of field using name instead of index |
| `__data.fields["NameOfField"]` | Value of field using name instead of index |
| `__data.fields[1].labels.cluster` | Access labels of another field |
## Template variables
### Template variables
When linking to another dashboard that uses template variables, select variable values for whoever clicks the link.
@@ -97,54 +132,69 @@ When linking to another dashboard that uses template variables, select variable
If you want to add all of the current dashboard's variables to the URL, then use `${__all_variables}`.
## Data links
## Add a data link
Data links allow you to provide more granular context to your links. You can create links that include the series name or even the value under the cursor. For example, if your visualization showed four servers, you could add a data link to one or two of them.
The link itself is accessible in different ways depending on the visualization. For the Graph you need to click on a data point or line, for a panel like
Stat, Gauge, or Bar Gauge you can click anywhere on the visualization to open the context menu.
You can use variables in data links to send people to a detailed dashboard with preserved data filters. For example, you could use variables to specify a time range, series, and variable selection. For more information, refer to [Data link variables](#data-link-variables).
### Typeahead suggestions
When creating or updating a data link, press Cmd+Space or Ctrl+Space on your keyboard to open the typeahead suggestions to more easily add variables to your URL.
{{< figure src="/static/img/docs/data_link_typeahead.png" max-width= "800px" alt="Drop-down list with variable suggestions open from the URL field" >}}
### Add a data link
1. Hover over any part of the panel you want to which you want to add the data link to display the actions menu on the top right corner.
1. Click the menu and select **Edit**.
To use a keyboard shortcut to open the panel, hover over the panel and press `e`.
1. Scroll down to the Data links section and expand it.
1. Navigate to the panel to which you want to add the data link.
1. Hover over any part of the panel to display the menu icon in the upper-right corner.
1. Click the menu icon and select **Edit** to open the panel editor.
1. In the panel edit pane, scroll down to the **Data links** section and expand it.
1. Click **Add link**.
1. Enter a **Title**. **Title** is a human-readable label for the link that will be displayed in the UI.
1. Enter the **URL** you want to link to.
1. In the dialog box that opens, enter a **Title**. This is a human-readable label for the link, which will be displayed in the UI.
1. Enter the **URL** or variable to which you want to link.
You can even add one of the template variables defined in the dashboard. Click in the **URL** field and then type `$` or press Ctrl+Space or Cmd+Space to see a list of available variables. By adding template variables to your panel link, the link sends the user to the right context, with the relevant variables already set. For more information, refer to [Data link variables](#data-link-variables).
To add a data link variable, click in the **URL** field and enter `$` or press Ctrl+Space or Cmd+Space to see a list of available variables.
1. If you want the link to open in a new tab, then select **Open in a new tab**.
1. Click **Save** to save changes and close the window.
1. Click **Save** in the upper right to save your changes to the dashboard.
### Update a data link
1. Scroll down to the Data links section, expand it, and find the link that you want to make changes to.
1. Click the Edit (pencil) icon to open the Edit link window.
1. Make any necessary changes.
1. Click **Save** to save changes and close the window.
1. Click **Save** in the upper right to save your changes to the dashboard.
### Delete a data link
1. Scroll down to the Data links section, expand it, and find the link that you want to delete.
1. Click the **X** icon next to the link you want to delete.
1. Click **Save** in the upper right to save your changes to the dashboard.
1. If you want the link to open in a new tab, then toggle the **Open in a new tab** switch.
1. Click **Save** to save changes and close the dialog box.
1. Click **Apply** to see your changes in the dashboard.
1. Click the **Save dashboard** icon to save your changes to the dashboard.
{{% docs/reference %}}
[bar chart]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/bar-chart"
[bar chart]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/bar-chart"
[bar gauge]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/bar-gauge"
[bar gauge]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/bar-gauge"
[candlestick]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/candlestick"
[candlestick]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/candlestick"
[canvas]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/canvas"
[canvas]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/canvas"
[gauge]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/gauge"
[gauge]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/gauge"
[geomap]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/geomap"
[geomap]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/geomap"
[heatmap]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/heatmap"
[heatmap]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/heatmap"
[histogram]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/histogram"
[histogram]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/histogram"
[pie chart]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/pie-chart"
[pie chart]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/pie-chart"
[stat]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/stat"
[stat]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/stat"
[state timeline]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/state-timeline"
[state timeline]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/state-timeline"
[status history]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/status-history"
[status history]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/status-history"
[table]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/table"
[table]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/table"
[time series]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/time-series"
[time series]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/time-series"
[trend]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/trend"
[trend]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/trend"
[Cloudwatch]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/datasources/aws-cloudwatch/query-editor#deep-link-grafana-panels-to-the-cloudwatch-console-1"
[Cloudwatch]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/connect-externally-hosted/data-sources/aws-cloudwatch/query-editor#deep-link-grafana-panels-to-the-cloudwatch-console-1"
@@ -152,8 +202,8 @@ When creating or updating a data link, press Cmd+Space or Ctrl+Space on your key
[Google Cloud Monitoring]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/connect-externally-hosted/data-sources/google-cloud-monitoring/query-editor#deep-link-from-grafana-panels-to-the-google-cloud-console-metrics-explorer"
[Templates and variables]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/dashboards/variables"
[Templates and variables]: "/docs/grafana-cloud/ -> /docs/grafana/<GRAFANA VERSION>/dashboards/variables"
[Templates and variables]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/dashboards/variables"
[Global variables]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/dashboards/variables/add-template-variables#**from-and-**to"
[Global variables]: "/docs/grafana-cloud/ -> /docs/grafana/<GRAFANA VERSION>/dashboards/variables/add-template-variables#**from-and-**to"
[Global variables]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/dashboards/variables/add-template-variables#**from-and-**to"
{{% /docs/reference %}}

View File

@@ -16,34 +16,55 @@ labels:
- oss
menuTitle: Configure value mappings
title: Configure value mappings
description: Configure value mappings to change the visual treatment of data in your visualizations
description: Configure value mappings to change how data appears in your visualizations
weight: 90
---
# Configure value mappings
In addition to field overrides, value mapping is a technique that you can use to change the visual treatment of data that appears in a visualization.
In addition to field overrides, value mapping is a technique you can use to change how data appears in a visualization.
Values mapped using value mappings bypass the unit formatting. This means that a text value mapped to a numerical value is not formatted using the configured unit.
For example, the mapping applied in the following image causes the visualization to display the text `Cold`, `Good`, and `Hot` in blue, green, and red for ranges of temperatures rather than actual temperature values. Using value mappings this way can make data faster and easier to understand and interpret.
![Value mappings example](/static/img/docs/value-mappings/value-mappings-example-8-0.png)
![Value mappings applied to a gauge visualization](/media/docs/grafana/panels-visualizations/screenshot-value-mappings-v10.4.png)
If value mappings are present in a panel, then Grafana displays a summary in the side pane of the panel editor.
Value mappings bypass unit formatting set in the **Standard options** section of panel editor, like color or number of decimal places displayed. When value mappings are present in a panel, Grafana displays a summary of them in the **Value mappings** section of the editor panel.
## Supported visualizations
You can configure value mappings for the following visualizations:
| | | |
| -------------------------- | -------------------------------- | -------------------------------- |
| [Bar chart][bar chart] | [Geomap][geomap] | [Status history][status history] |
| [Bar gauge][bar gauge] | [Histogram][histogram] | [Table][table] |
| [Candlestick][candlestick] | [Pie chart][pie chart] | [Time series][time series] |
| [Canvas][canvas] | [Stat][stat] | [Trend][trend] |
| [Gauge][gauge] | [State timeline][state timeline] | |
## Types of value mappings
{{% admonition type="note" %}}
The new value mappings are not compatible with some visualizations, such as Graph (old), Text, and Heatmap.
{{% /admonition %}}
Grafana supports the following value mapping types:
Grafana supports the following value mappings:
### Value
- **Value:** Maps text values to a color or different display text. For example, you can configure a value mapping so that all instances of the value `10` appear as **Perfection!** rather than the number.
- **Range:** Maps numerical ranges to a display text and color. For example, if a value is within a certain range, you can configure a range value mapping to display **Low** or **High** rather than the number.
- **Regex:** Maps regular expressions to replacement text and a color. For example, if a value is `www.example.com`, you can configure a regex value mapping so that Grafana displays **www** and truncates the domain.
- **Special** Maps special values like `Null`, `NaN` (not a number), and boolean values like `true` and `false` to a display text and color. For example, you can configure a special value mapping so that `null` values appear as **N/A**.
A **Value** mapping maps specific values to text and a color. For example, you can configure a mapping so that all instances of the value `10` appear as **Perfection!** rather than the number. Use **Value** mapping when you want to format a single value.
![The value 10 mapped to the text Perfection!](/media/docs/grafana/panels-visualizations/screenshot-map-value-v10.4.png)
You can also use the dots on the left to drag and reorder value mappings in the list.
### Range
A **Range** mapping maps numerical ranges to text and a color. For example, if a value is within a certain range, you can configure a range value mapping to display **Low** or **High** rather than the number. Use **Range** mapping when you want to format multiple, continuous values.
![Ranges of numbers mapped to the text Low and High with colors yellow and red](/media/docs/grafana/panels-visualizations/screenshot-map-range-v10.4.png)
### Regex
A **Regex** mapping maps regular expressions to text and a color. For example, if a value is `www.example.com`, you can configure a regular expression value mapping so that Grafana displays **www** and truncates the domain. Use the **Regex** mapping when you want to format the text and color of a regular expression value.
![A regular expression used to truncate full URLs to the text wwww](/media/docs/grafana/panels-visualizations/screenshot-map-regex-v10.4.png)
### Special
A **Special** mapping maps special values like `Null`, `NaN` (not a number), and boolean values like `true` and `false` to text and color. For example, you can configure a special value mapping so that `null` values appear as **N/A**. Use the **Special** mapping when you want to format uncommon, boolean, or empty values.
![The value null mapped to the text N/A](/media/docs/grafana/panels-visualizations/screenshot-map-special-v10.4.png)
## Examples
@@ -51,19 +72,19 @@ Refer to the following examples to learn more about value mapping.
### Time series example
The following image shows a time series visualization with value mappings. Value mapping colors are not applied to this visualization, but the display text is shown on the axis.
The following image shows a time series visualization with value mappings. Value mapping colors aren't applied to this visualization, but the display text is shown on the axis.
![Value mappings time series example](/static/img/docs/value-mappings/value-mappings-summary-example-8-0.png)
### Stat example
The following image shows a Stat visualization with value mappings and text colors applied. You can hide the sparkline so it doesn't interfere with the values.
The following image shows a stat visualization with value mappings and text colors applied. You can hide the sparkline so it doesn't interfere with the values.
![Value mappings stat example](/static/img/docs/value-mappings/value-mappings-stat-example-8-0.png)
### Bar gauge example
The following image shows a bar gauge visualization with value mappings. The value mapping colors are applied to the text, but not to the gauges.
The following image shows a bar gauge visualization with value mappings. Note that the value mapping colors are applied to the text, but not to the gauges.
![Value mappings bar gauge example](/static/img/docs/value-mappings/value-mappings-bar-gauge-example-8-0.png)
@@ -73,64 +94,67 @@ The following image shows a table visualization with value mappings. If you want
![Value mappings table example](/static/img/docs/value-mappings/value-mappings-table-example-8-0.png)
## Map a value
## Add a value mapping
Map a value when you want to format a single value.
1. Navigate to the panel you want to update.
1. Hover over any part of the panel you want to work on to display the menu on the top right corner.
1. Click the menu and select **Edit**.
1. Scroll to the **Value mappings** section and expand it.
1. Click **Add value mappings**.
1. Click **Add a new mapping** and then select one of the following:
- **Value** - Enter a single value to match.
- **Range** - Enter the beginning and ending values of a range to match.
- **Regex** - Enter a regular expression pattern to match.
- **Special** - Select a special value to match.
1. Open a panel for which you want to map a value.
1. In panel display options, locate the **Value mappings** section and click **Add value mappings**.
1. Click **Add a new mapping** and then select **Value**.
1. Enter the value for Grafana to match.
1. (Optional) Enter display text.
1. (Optional) Set the color.
1. (Optional) Set an icon (canvas visualizations only).
1. Click **Update** to save the value mapping.
![Map a value](/static/img/docs/value-mappings/map-value-8-0.png)
After you've added a mapping, the **Edit value mappings** button replaces the **Add value mappings** button. Click the edit button to add or update mappings.
## Map a range
{{% docs/reference %}}
[bar chart]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/bar-chart"
[bar chart]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/bar-chart"
Map a range of values when you want to format multiple, continuous values.
[bar gauge]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/bar-gauge"
[bar gauge]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/bar-gauge"
1. Edit the panel for which you want to map a range of values.
1. In panel display options, in the **Value mappings** section, click **Add value mappings**.
1. Click **Add a new mapping** and then select **Range**.
1. Enter the beginning and ending values in the range for Grafana to match.
1. (Optional) Enter display text.
1. (Optional) Set the color.
1. Click **Update** to save the value mapping.
[candlestick]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/candlestick"
[candlestick]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/candlestick"
![Map a range](/static/img/docs/value-mappings/map-range-8-0.png)
[canvas]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/canvas"
[canvas]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/canvas"
## Map a regular expression
[gauge]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/gauge"
[gauge]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/gauge"
Map a regular expression when you want to format the text and color of a regular expression value.
[geomap]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/geomap"
[geomap]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/geomap"
1. Edit the panel for which you want to map a regular expression.
1. In the **Value mappings** section of the panel display options, click **Add value mappings**.
1. Click **Add a new mapping** and then select **Regex**.
1. Enter the regular expression pattern for Grafana to match.
1. (Optional) Enter display text.
1. (Optional) Set the color.
1. Click **Update** to save the value mapping.
[histogram]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/histogram"
[histogram]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/histogram"
## Map a special value
[pie chart]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/pie-chart"
[pie chart]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/pie-chart"
Map a special value when you want to format uncommon, boolean, or empty values.
[stat]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/stat"
[stat]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/stat"
1. Edit the panel for which you want to map a special value.
1. In panel display options, locate the **Value mappings** section and click **Add value mappings**.
1. Click **Add a new mapping** and then select **Special**.
1. Select the special value for Grafana to match.
1. (Optional) Enter display text.
1. (Optional) Set the color.
1. Click **Update** to save the value mapping.
[state timeline]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/state-timeline"
[state timeline]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/state-timeline"
![Map a value](/static/img/docs/value-mappings/map-special-value-8-0.png)
[status history]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/status-history"
[status history]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/status-history"
## Edit a value mapping
[table]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/table"
[table]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/table"
You can edit a value mapping at any time.
[time series]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/time-series"
[time series]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/time-series"
1. Edit the panel that contains the value mapping you want to edit.
1. In the panel display options, in the **Value mappings** section, click **Edit value mappings**.
1. Make the changes and click **Update**.
[trend]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/trend"
[trend]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/trend"
{{% /docs/reference %}}

View File

@@ -369,7 +369,7 @@ The maximum number of connections in the idle connection pool.
### max_open_conn
The maximum number of open connections to the database.
The maximum number of open connections to the database. For MYSQL, configure this setting on both Grafana and the database. For more information, refer to [`sysvar_max_connections`](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_max_connections).
### conn_max_lifetime

View File

@@ -170,6 +170,7 @@ Experimental features might be changed or removed without prior notice.
| `logRowsPopoverMenu` | Enable filtering menu displayed when text of a log line is selected |
| `pluginsSkipHostEnvVars` | Disables passing host environment variable to plugin processes |
| `tableSharedCrosshair` | Enables shared crosshair in table panel |
| `newFolderPicker` | Enables the nested folder picker without having nested folders enabled |
## Development feature toggles

View File

@@ -33,11 +33,11 @@ Request security is available in Grafana Enterprise v7.4 and later versions.
Configure a firewall to restrict Grafana from making network requests to sensitive internal web services.
There are many firewall tools available, refer to the documentation for your specific security tool. For example, Linux users can use [iptables](https://en.wikipedia.org/wiki/Iptables).
There are many firewall tools available. Refer to the documentation for your specific security tool. For example, Linux users can use [iptables](https://en.wikipedia.org/wiki/Iptables).
## Proxy server
Require all network requests being made by Grafana to go through a proxy server.
You can require all network requests made by Grafana to go through a proxy server.
Self-hosted reverse proxy options include but are not limited to:
@@ -47,9 +47,9 @@ Self-hosted reverse proxy options include but are not limited to:
## Limit Viewer query permissions
Users with the Viewer role can enter _any possible query_ in _any_ of the data sources available in the **organization**, not just the queries that are defined on the dashboards for which the user has Viewer permissions.
Users with the `Viewer role` can enter _any possible query_ in _any_ of the data sources available in the **organization**, not just the queries that are defined on the dashboards for which the user has Viewer permissions.
**For example:** In a Grafana instance with one data source, one dashboard, and one panel that has one query defined, you might assume that a Viewer can only see the result of the query defined in that panel. Actually, the Viewer has access to send any query to the data source. With a command-line tool like curl (there are lots of tools for this), the Viewer can make their own query to the data source and potentially access sensitive data.
For example, in a Grafana instance with one data source, one dashboard, and one panel that has one query defined, you might assume that a Viewer can only see the result of the query defined in that panel. Actually, the Viewer has access to send any query to the data source. With a command-line tool like curl (there are many tools for this), the Viewer can make their own query to the data source and potentially access sensitive data.
To address this vulnerability, you can restrict data source query access in the following ways:
@@ -58,8 +58,10 @@ To address this vulnerability, you can restrict data source query access in the
## Implications of enabling anonymous access to dashboards
When you enable anonymous access to a dashboard, it is publicly available. This section lists the security implications of enabling Anonymous access.
When you enable anonymous access in Grafana, any visitor or user can use Grafana as a Viewer without signing in. This section lists the security implications of enabling Anonymous access.
- Anyone with the URL can access the dashboard.
- Anyone can make view calls to the API and list all folders, dashboards, and data sources.
- Anyone with the URL of a dashboard accessible by the Viewer role can access that dashboard.
- New dashboards are publicly available unless the dashboard creator hides them from **all Viewers**.
- Anyone can edit or delete dashboards that have granted Edit or Admin abilities to Viewers.
- Anyone can make `view` calls to the API and list all folders, dashboards, and data sources.
- Anyone can make arbitrary queries to any data source that the Grafana instance is configured with.

View File

@@ -326,6 +326,40 @@ Payload:
This section includes examples of setting up generic OAuth2 integration.
### Set up OAuth2 with Descope
To set up generic OAuth2 authentication with Descope, follow these steps:
1. Create a Descope Project [here](https://app.descope.com/gettingStarted), and go through the Getting Started Wizard to configure your authentication. You can skip step if you already have Descope project set up.
1. If you wish to use a flow besides `Sign Up or In`, go to the **IdP Applications** menu in the console, and select your IdP application. Then alter the **Flow Hosting URL** query parameter `?flow=sign-up-or-in` to change which flow id you wish to use.
1. Click **Save**.
1. Update the `[auth.generic_oauth]` section of the Grafana configuration file using the values from the **Settings** tab:
{{% admonition type="note" %}}
You can get your Client ID (Descope Project ID) under [Project Settings](https://app.descope.com/settings/project). Your Client Secret (Descope Access Key) can be generated under [Access Keys](https://app.descope.com/accesskeys).
{{% /admonition %}}
```bash
[auth.generic_oauth]
enabled = true
allow_sign_up = true
auto_login = false
team_ids =
allowed_organizations =
name = Descope
client_id = <Descope Project ID>
client_secret = <Descope Access Key>
scopes = openid profile email descope.claims descope.custom_claims
auth_url = https://api.descope.com/oauth2/v1/authorize
token_url = https://api.descope.com/oauth2/v1/token
api_url = https://api.descope.com/oauth2/v1/userinfo
use_pkce = true
use_refresh_token = true
```
### Set up OAuth2 with Auth0
To set up generic OAuth2 authentication with Auth0, follow these steps:

View File

@@ -18,9 +18,11 @@ weight: 300
The LDAP integration in Grafana allows your Grafana users to login with their LDAP credentials. You can also specify mappings between LDAP
group memberships and Grafana Organization user roles.
> [Enhanced LDAP authentication]({{< relref "../enhanced-ldap" >}}) is available in [Grafana Cloud](/docs/grafana-cloud/) and in [Grafana Enterprise]({{< relref "../../../../introduction/grafana-enterprise" >}}).
{{% admonition type="note" %}}
[Enhanced LDAP authentication]({{< relref "../enhanced-ldap" >}}) is available in [Grafana Cloud](/docs/grafana-cloud/) and in [Grafana Enterprise]({{< relref "../../../../introduction/grafana-enterprise" >}}).
{{% /admonition %}}
> Refer to [Role-based access control]({{< relref "../../../../administration/roles-and-permissions/access-control" >}}) to understand how you can control access with role-based permissions.
Refer to [Role-based access control]({{< relref "../../../../administration/roles-and-permissions/access-control" >}}) to understand how you can control access with role-based permissions.
## Supported LDAP Servers
@@ -127,6 +129,10 @@ member_of = "memberOf"
email = "email"
```
{{% admonition type="note" %}}
Whenever you modify the ldap.toml file, you must restart Grafana in order for the change(s) to take effect.
{{% /admonition %}}
### Using environment variables
You can interpolate variables in the TOML configuration from environment variables. For instance, you could externalize your `bind_password` that way:
@@ -135,17 +141,19 @@ You can interpolate variables in the TOML configuration from environment variabl
bind_password = "${LDAP_ADMIN_PASSWORD}"
```
## LDAP Debug View
## LDAP debug view
> Only available in Grafana v6.4+
{{% admonition type="note" %}}
Available in Grafana v6.4+
{{% /admonition %}}
Grafana has an LDAP debug view built-in which allows you to test your LDAP configuration directly within Grafana. At the moment of writing, only Grafana admins can use the LDAP debug view.
Grafana has an LDAP debug view built-in which allows you to test your LDAP configuration directly within Grafana. Only Grafana admins can use the LDAP debug view.
Within this view, you'll be able to see which LDAP servers are currently reachable and test your current configuration.
{{< figure src="/static/img/docs/ldap_debug.png" class="docs-image--no-shadow" max-width="600px" >}}
To use the debug view:
To use the debug view, complete the following steps:
1. Type the username of a user that exists within any of your LDAP server(s)
1. Then, press "Run"
@@ -157,9 +165,7 @@ To use the debug view:
{{< figure src="/static/img/docs/ldap_sync_debug.png" class="docs-image--no-shadow" max-width="600px" >}}
### Bind
#### Bind and Bind Password
### Bind and bind password
By default the configuration expects you to specify a bind DN and bind password. This should be a read only user that can perform LDAP searches.
When the user DN is found a second bind is performed with the user provided username and password (in the normal Grafana login form).
@@ -169,7 +175,7 @@ bind_dn = "cn=admin,dc=grafana,dc=org"
bind_password = "grafana"
```
#### Single Bind Example
#### Single bind example
If you can provide a single bind expression that matches all possible users, you can skip the second bind and bind against the user DN directly.
This allows you to not specify a bind_password in the configuration file.
@@ -183,7 +189,7 @@ The search filter and search bases settings are still needed to perform the LDAP
### POSIX schema
If your LDAP server does not support the memberOf attribute add these options:
If your LDAP server does not support the `memberOf` attribute, add the following options:
```bash
## Group search filter, to retrieve the groups of which the user is a member (only set if memberOf attribute is not available)
@@ -194,7 +200,7 @@ group_search_base_dns = ["ou=groups,dc=grafana,dc=org"]
group_search_filter_user_attribute = "uid"
```
### Group Mappings
### Group mappings
In `[[servers.group_mappings]]` you can map an LDAP group to a Grafana organization and role. These will be synced every time the user logs in, with LDAP being the authoritative source.
@@ -231,8 +237,12 @@ org_role = "Viewer"
| `org_id` | No | The Grafana organization database id. Setting this allows for multiple group_dn's to be assigned to the same `org_role` provided the `org_id` differs | `1` (default org id) |
| `grafana_admin` | No | When `true` makes user of `group_dn` Grafana server admin. A Grafana server admin has admin access over all organizations and users. Available in Grafana v5.3 and above | `false` |
Note: Commenting out a group mapping requires also commenting out the header of
said group or it will fail validation as an empty mapping. Example:
{{% admonition type="note" %}}
Commenting out a group mapping requires also commenting out the header of
said group or it will fail validation as an empty mapping.
{{% /admonition %}}
Example:
```bash
[[servers]]
@@ -265,7 +275,7 @@ To configure `group_search_filter`:
**Active Directory example:**
Active Directory groups store the Distinguished Names (DNs) of members, so your filter will need to know the DN for the user based only on the submitted username.
Multiple DN templates can be searched by combining filters with the LDAP OR-operator. Two examples:
Multiple DN templates are searched by combining filters with the LDAP OR-operator. Two examples:
```bash
group_search_filter = "(member:1.2.840.113556.1.4.1941:=%s)"
@@ -281,10 +291,12 @@ group_search_filter_user_attribute = "cn"
For more information on AD searches see [Microsoft's Search Filter Syntax](https://docs.microsoft.com/en-us/windows/desktop/adsi/search-filter-syntax) documentation.
For troubleshooting, by changing `member_of` in `[servers.attributes]` to "dn" it will show you more accurate group memberships when [debug is enabled](#troubleshooting).
For troubleshooting, changing `member_of` in `[servers.attributes]` to "dn" will show you more accurate group memberships when [debug is enabled](#troubleshooting).
## Configuration examples
The following examples describe different LDAP configuration options.
### OpenLDAP
[OpenLDAP](http://www.openldap.org/) is an open source directory service.

View File

@@ -15,7 +15,7 @@ weight: 400
This topic guides you through installing Grafana via the official Docker images. Specifically, it covers running Grafana via the Docker command line interface (CLI) and docker-compose.
{{< youtube id="FlDfcMbSLXs" >}}
{{< youtube id="FlDfcMbSLXs" start="703">}}
Grafana Docker images come in two editions:

View File

@@ -15,7 +15,7 @@ weight: 500
On this page, you will find instructions for installing and running Grafana on Kubernetes using Kubernetes manifests for the setup. If Helm is your preferred option, refer to [Grafana Helm community charts](https://github.com/grafana/helm-charts).
Watch this video to learn more about installing Grafana on Kubernetes: {{< vimeo 871940219 >}}
Watch this video to learn more about installing Grafana on Kubernetes: {{< youtube id="DEv5wtZxNCk" start="1872">}}
## Before you begin

View File

@@ -61,6 +61,10 @@ To install Grafana on macOS using the standalone binaries, complete the followin
./bin/grafana server
```
Alternatively, watch the Grafana for Beginners video below:
{{< youtube id="T51Qa7eE3W8" >}}
## Next steps
- [Start the Grafana server]({{< relref "../../start-restart-grafana" >}})

View File

@@ -86,6 +86,8 @@ Query results for both the editor and the builder are returned in a table. Selec
Selecting the trace ID from the returned results opens a trace diagram. Selecting a span from the returned results opens a trace diagram and reveals the relevant span in the trace diagram (above, the highlighted blue line).
In the trace diagram, the bold text on the left side of each span indicates the service name, for example `mythical-requester: requester`, and it is hidden when subsequent spans have the same service name (nested spans). Each service has a color assigned to it, which is visible to the left of the name and timeline in the graph. Spans with the same color belong to the same service. The grey text to the right of the service name indicates the span name.
### Streaming results
The Tempo data source supports streaming responses to TraceQL queries so you can see partial query results as they come in without waiting for the whole query to finish.

View File

@@ -0,0 +1,23 @@
---
description: Guide for upgrading to Grafana v10.3
keywords:
- grafana
- configuration
- documentation
- upgrade
- '10.3'
- '10.2.3'
title: Upgrade to Grafana v10.3
menuTitle: Upgrade to v10.3
weight: 1400
---
# Upgrade to Grafana v10.3
{{< docs/shared lookup="upgrade/intro.md" source="grafana" version="<GRAFANA VERSION>" >}}
{{< docs/shared lookup="back-up/back-up-grafana.md" source="grafana" version="<GRAFANA VERSION>" leveloffset="+1" >}}
{{< docs/shared lookup="upgrade/upgrade-common-tasks.md" source="grafana" version="<GRAFANA VERSION>" >}}
## Technical notes

View File

@@ -76,6 +76,7 @@ For a complete list of every change, with links to pull requests and related iss
## Grafana 10
- [What's new in 10.3](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/whatsnew/whats-new-in-v10-3/)
- [What's new in 10.2](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/whatsnew/whats-new-in-v10-2/)
- [What's new in 10.1]({{< relref "whats-new-in-v10-1/" >}})
- [What's new in 10.0]({{< relref "whats-new-in-v10-0/" >}})

View File

@@ -100,7 +100,7 @@ You can now use generative AI to assist you in your Grafana dashboards. So far g
- **Generate panel and dashboard titles and descriptions** - You can now generate a title and description for your panel or dashboard based on the data you've added to it. This is useful when you want to quickly visualize your data and don't want to spend time coming up with a title or description.
- **Generate dashboard save changes summary** - You can now generate a summary of the changes you've made to a dashboard when you save it. This is great for effortlessly tracking the history of a dashboard.
To enable these features, you must first enable the `dashgpt` [feature toggle](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/feature-toggles/#experimental-feature-toggles). Then install and configure Grafana's LLM app plugin. For more information, refer to the [Grafana LLM app plugin documentation](https://grafana.com/docs/grafana-cloud/alerting-and-irm/machine-learning/llm-plugin/).
To enable these features, you must first enable the `dashgpt` [feature toggle](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/feature-toggles/#experimental-feature-toggles). Then install and configure Grafana's LLM app plugin. For more information, refer to the [Grafana LLM app plugin documentation](https://grafana.com/docs/grafana-cloud/alerting-and-irm/machine-learning/configure/llm-plugin/).
When enabled, look for the **✨ Auto generate** option next to the **Title** and **Description** fields in your panels and dashboards, or when you press the **Save** button.

View File

@@ -0,0 +1,420 @@
---
description: Feature and improvement highlights for Grafana v10.3
keywords:
- grafana
- new
- documentation
- '10.3'
- '10.2.3'
- release notes
labels:
products:
- cloud
- enterprise
- oss
title: What's new in Grafana v10.3
weight: -40
---
# Whats new in Grafana v10.3
Welcome to Grafana 10.3! Read on to learn about changes to navigation, visualizations and transformations, alerting, profiling, and logs.
We've also included here features released in Grafana 10.2.3, as well as breaking changes from that release. Features that were included in the 10.2.3 release are marked with an asterisk.
For even more detail about all the changes in this release, refer to the [changelog](https://github.com/grafana/grafana/blob/master/CHANGELOG.md). For the specific steps we recommend when you upgrade to v10.3, check out our [Upgrade Guide](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/upgrade-guide/upgrade-v10.3/).
## Breaking changes
For Grafana v10.3, we've also provided a list of [breaking changes](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/breaking-changes/breaking-changes-v10-3) to help you upgrade with greater confidence. For information about these along with guidance on how to proceed, refer to [Breaking changes in Grafana v10.3](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/breaking-changes/breaking-changes-v10-3/).
<!-- Template below
## Feature
<!-- Name of contributor -->
<!--_[Generally available | Available in private/public preview | Experimental] in Grafana [Open Source, Enterprise, all editions of Grafana, some combination of self-managed and Cloud]_
Description. Include an overview of the feature and problem it solves, and where to learn more (like a link to the docs).
{{% admonition type="note" %}}
Use full URLs for links. When linking to versioned docs, replace the version with the version interpolation placeholder (for example, <GRAFANA_VERSION>, <TEMPO_VERSION>, <MIMIR_VERSION>) so the system can determine the correct set of docs to point to. For example, "https://grafana.com/docs/grafana/latest/administration/" becomes "https://grafana.com/docs/grafana/<GRAFANA_VERSION>/administration/".
{{% /admonition %}}
<!--Add an image, GIF or video as below-->
<!--{{< figure src="/media/docs/grafana/dashboards/WidgetVizSplit.png" max-width="750px" caption="DESCRIPTIVE CAPTION" >}}
<!--Learn how to upload images here: https://grafana.com/docs/writers-toolkit/write/image-guidelines/#where-to-store-media-assets-->
<!---->
## Navigation updates\*
<!--Laura Benz-->
_Available in public preview in Grafana Open Source and Enterprise_
The improved navigation menu gives you a better overview by showing all levels of navigation items in a more compact design. We also implemented a better dock and improved scrolling behavior. Furthermore, we improved the structure of the nav menu and added several new items.
{{< youtube id="IhpghtVykLc" >}}
## Table data in PDF reports
<!--Agnès Toulet-->
_Available in public preview in Grafana Enterprise and Grafana Cloud_
We've improved the reporting experience with options to make all of your table data accessible in PDFs. Previously, if your dashboard included large table visualizations, you couldn't see all of the table data in your PDF report. Unlike in Grafana, you couldn't scroll in the PDF table visualization or click on the page numbers. With this new feature, you now have the option to see all the data directly in your PDF without losing your dashboard layout.
We've added two format options to the report creation form:
- **Include table data as PDF appendix** - Adds an appendix to your dashboard PDF.
- **Attach a separate PDF of table data** - Generates a separate PDF file for your table panel data.
To try out this feature, enable the `pdfTables` [feature toggle](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/feature-toggles/) or contact Grafana Support to have it enabled in on your Grafana Cloud stack.
{{< youtube id="1fzQQI8O838" >}}
## Dashboards and visualizations
### Moving average and trend lines using transformations
<!--Oscar Kilhed-->
_Available in public preview in all editions of Grafana_
#### Moving average\*
Sometimes your data is too noisy to quickly grasp what's going on. A common way to address this issue is to calculate the moving mean, or moving average, to filter out some of that noise. Luckily, many data sources already support calculating the moving mean, but when the support is lacking or you're not well versed in the query language, until now, you were stuck with the noise.
{{< figure src="/media/docs/grafana/transformations/noisy-sensor-data.png" caption="Noisy data can hide the general trend of your data." alt="Graph displaying noisy sensor data" max-width="300px" >}}
By selecting the **Window functions** mode and using **Mean** as the calculation for the **Add field from calculation** transformation, Grafana adds a field with the moving mean for your selected field.
{{< figure src="/media/docs/grafana/transformations/noisy-sensor-data-moving-average.png" caption="Calculating the moving mean of your data will make it easier to grasp what's going on." alt="Graph displaying the moving mean of noisy data" >}}
The **Window functions** mode also supports moving variance and moving standard deviation calculations if you need to analyze the volatility of your metric.
[Documentation](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/panels-visualizations/query-transform-data/transform-data/#add-field-from-calculation)
#### Trend lines\*
We're also adding some basic statistical analysis features as a way to help you visualize trends in your data. The **Regression analysis** transformation will fit a mathematical function to your data and display it as predicted data points in a separate data frame.
{{< figure src="/media/docs/grafana/transformations/trendlines.png" caption="Linear and polynomial regression trendlines" alt="Graph with trendlines" >}}
The transformation currently supports linear regression and polynomial regression to the fifth-degree.
### Canvas visualization supports pan and zoom
<!--Nathan Marrs-->
_Available in public preview in all editions of Grafana_
Canvas visualizations now support panning and zooming. This allows you to both create and navigate more complex designs.
To enable this feature, you must first enable the `canvasPanelPanZoom` [feature toggle](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/feature-toggles/).
{{< youtube id="CF-HFkcytRA" >}}
[Documentation](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/panels-visualizations/visualizations/canvas/)
### Improved tooltips in visualizations\*
<!--Nathan Marrs-->
_Available in public preview in all editions of Grafana_
We've introduced enhanced tooltips as part of our standardization initiative, unifying the tooltip architecture for a consistent user experience across panels. Packed with features like color indicators, time uniformity, and improved support for long labels, these tooltips go beyond a cosmetic redesign, bringing fundamental changes to elevate your data visualization experience. Stay tuned for more updates!
To try out the new tooltips, enable the `newVizTooltips` [feature toggle](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/feature-toggles/). Enhanced tooltips have been implemented for the following visualizations:
- Time series
- Trend
- Heatmap
- Status history
- Candlestick
- State timeline
- XY Chart
- and more coming soon!
{{% admonition type="note" %}}
As this is an ongoing project, the dashboard shared cursor and annotations features are not yet fully supported.
{{% /admonition %}}
{{< youtube id="0Rp6FYfHu6Q" >}}
### Plot enum values in your time series and state timeline visualizations\*
<!--Nathan Marrs-->
_Generally available in all editions of Grafana_
You can now plot enum values in your time series and state timeline visualizations. This feature is useful when you want to visualize the state of a system, such as the status of a service or the health of a device. For example, you can use this feature to visualize the status of a service as `ON`, `STANDBY`, or `OFF`. To display enum values you can [use the convert field transform](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/panels-visualizations/query-transform-data/transform-data/#convert-field-type).
{{< youtube id="FG0hBFfgpps" >}}
### View percent change in stat visualizations
<!--Nathan Marrs-->
_Generally available in all editions of Grafana_
You can now view percent change in stat visualizations. This makes it easier to understand your data by showing how metrics are changing over time.
{{< youtube id="mB9FU0myZo8" >}}
[Documentation](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/panels-visualizations/visualizations/stat/#show-percent-change)
### Data visualization quality of life improvements
<!--Nathan Marrs-->
_Generally available in all editions of Grafana_
Weve made a few smaller improvements to the data visualization experience in Grafana.
#### Apply data transformations to annotations
You can now apply data transformations to annotation data. For example, you can now configure how exemplar data is displayed in tooltips.
{{< video-embed src="/media/docs/grafana/screen-recording-10-3-data-transformations-annotation-support.mp4" caption="Configure how exemplar data appears in tooltip" >}}
#### Disable auto scaling units
By default, Grafana automatically scales the unit based on the magnitude of the value. For example, if you have a value of 0.14 kW, Grafana will display it as 140 W. You can now disable unit auto scaling. This is helpful in cases where you want to ensure that the same unit is shown in your visualization regardless of the magnitude of the data. See [the standard options documentation](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/panels-visualizations/configure-standard-options/#scale-units) for more information.
{{< video-embed src="/media/docs/grafana/screen-recording-10-3-disable-unit-auto-scaling.mp4" caption="Disable auto scaling units" >}}
### New Transformations UI experience and documentation upgrades
<!--Jev Forsberg-->
_Generally available in all editions of Grafana_
We've revamped the Transformations user interface to make it cleaner, more user-friendly, and overall better for visualizing, selecting, and comprehending transformation options for your data.
#### Improved UI\*
In the past, transformations were applied through a dropdown menu, indicated solely by text names like Merge, Sort, JoinByLabels, etc. Now, we've introduced a much more user-friendly interface. A convenient drawer allows seamless access to all transformation options, each accompanied by visual/graphical representations and a brief description. These enhancements are designed to enhance the user's comprehension of their data transformation choices.
{{< figure src="/media/docs/grafana/transformations/transformations_ui_drawer_selector.png" caption="The new Transformation UI drawer" alt="Transformation UI drawer" >}}
#### In-App documentation
We've also streamlined the user experience by integrating documentation directly into the core Grafana application. Gone are the days of navigating to a separate browser page for Transformation documentation. Now, users can conveniently access documentation within the app interface, providing a more seamless and efficient way to understand and utilize various features. This enhancement aims to save time and enhance user convenience, ensuring that valuable information is readily available at their fingertips.
{{< figure src="/media/docs/grafana/transformations/transformations_internal_documentation.png" caption="Transformation documentation is now internally available inside the Grafana app itself." alt="Transformation documentation internally available" >}}
### Copy and paste time range
<!--Haris Rozajac-->
_Generally available in all editions of Grafana_
Copying and pasting time range in the time range picker is now available. For example, you can copy a time range in **Explore** and paste it into **Dashboards** and vice versa. You can also copy and paste a time range using the new keyboard shortcuts `t+c` and `t+v`, respectively.
## Profiles
### Trace to Profiles\*
<!--Joey Tawadrous-->
_Experimental in all editions of Grafana_
Using Trace to profiles, you can use Grafanas ability to correlate different signals by adding the functionality to link between traces and profiles.
**Trace to profiles** lets you link your Grafana Pyroscope data source to tracing data. When configured, this connection lets you run queries from a trace span into the profile data.
There are two ways to configure the trace to profiles feature:
- Use a simplified configuration with default query, or
- Configure a custom query where you can use a template language to interpolate variables from the trace or span.
{{< figure src="/static/img/docs/tempo/profiles/tempo-trace-to-profile.png" caption="Trace to profiles screenshot" alt="Trace to profiles screenshot" >}}
To try out **Trace to profiles**, enable the 'traceToProfiles' feature toggle.
If you would also like to try out the **Embedded Flame Graph** feature, please enable the 'tracesEmbeddedFlameGraph' feature toggle.
Note: in order to determine that there is a profile for a given span and render the 'Profiles for this span' button or the embedded flame graph in the span details, the 'pyroscope.profile.id' key-value pair must exist in your span tags.
{{< youtube id="AG8VzfFMLxo" >}}
[Documentation](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/datasources/tempo/configure-tempo-data-source/#trace-to-profiles)
### FlameGraph: Collapsing similar items in the graph\*
<!--Andrej Ocenas-->
_Experimental in all editions of Grafana_
Sometimes profile stacks contain lots of levels with similar repeating items, for example long stacks of framework code that usually isn't of interest but takes up a lot of visual real estate. With this feature, instead of rendering all of the similar items we render only one and allow to expand those collapsed items on demand.
To try it out, enable the traceToProfiles feature toggle. To enable it in your Grafana Cloud stack, contact Grafana Support.
{{< youtube id="Y1c32Cf5nSE" >}}
## Alerting
### Alerting insights\*
<!-- George Robinson -->
_Generally available in all editions of Grafana_
Use Alerting insights to monitor your alerting data, discover key trends about your organizations alert management performance, and find patterns in why things go wrong.
### Export alerting resources to Terraform
<!-- Yuri Tseretyan-->
_Generally available in all editions of Grafana_
Export your alerting resources, such as alert rules, contact points, and notification policies as Terraform resources. A new “Modify export” mode for alert rules enables you to edit provisioned alert rules and export a modified version.
### Contact points list view redesign
<!-- Brenda Muir -->
_Generally available in all editions of Grafana_
The Contact points list view has been redesigned and split into two tabs: Contact Points and Notification Templates, making it easier to view all contact point information at a glance. You can now search for name and type of contact points and integrations, view how many notification policies each contact point is being used for, and navigate directly to the linked notification policies.
{{< youtube id="_eOhSmbYK8Q" >}}
### Create alerts from panels\*
<!-- Brenda Muir -->
_Generally available in all editions of Grafana_
Create alerts from dashboard panels. You can reuse the panel queries and create alerts based on them.
### Support for adding responders to Opsgenie alerting contact point\*
<!--Ryan Kehoe-->
_Generally available in all editions of Grafana_
The Opsgenie contact point has been extended to allow users to optionally fill out responder information for their integration. Responders tell Opsgenie who an alert should notify according to their escalation policies and routing rules.
### Recovery thresholds for alerts
<!--Ryan Kehoe-->
_Generally available in all editions of Grafana_
To reduce the noise of flapping alerts, you can set a recovery threshold different to the alert threshold.
Flapping alerts occur when a metric hovers around the alert threshold condition and may lead to frequent state changes, resulting in too many notifications being generated.
## Logs
### Logs Table UI
<!--Galen Kistler-->
_Available in public preview in all editions of Grafana_
Table view was created to help facilitate ease of use in a point and click UI, as opposed to datasource specific query language formatting options, like loki's line_format.
Tables can be configured and shared with team members via explore URLs or by adding the table to a dashboard panel.
{{< youtube id="OAZeqqNpEjc" >}}
## Data sources
### Data source Admin permission\*
<!--Ieva Vasiljeva-->
_Generally available in Grafana Enterprise and Grafana Cloud_
In addition to `Query` and `Edit` access, you can now grant users, teams, or basic roles `Admin` access to data sources. Users with `Admin` access to a data source can grant and revoke permissions to the data source, as well as to manage query caching settings for the data source. Users are automatically granted `Admin` access to data sources that they create.
### Redshift and Athena: Async query caching
<!--Isabella Siu-->
_Generally available in Grafana Enterprise, Grafana Cloud Advanced and Cloud Pro_
Introducing query caching for async queries in the Athena and Redshift data source plugins. We previously introduced async queries for the Athena and Redshift plugins, and this feature adds support for caching those queries. To use this, you must have query caching enabled for the Athena or Redshift data source you wish to cache. This feature was previously available behind a feature toggle and is now generally available and enabled by default.
{{% admonition type="note" %}}
The `useCachingService` feature toggle must also be enabled to use this feature.
{{% /admonition %}}
### Loki data source improvements: "or" filter syntax, filter by label types, derived fields by labels
<!--Sven Grossmann-->
<!--enablement videos to come?-->
_Generally available in all editions of Grafana_
Introducing several improvements to the Loki data source.
{{< youtube id="ievPSzmCrAk" >}}
#### Line filter "or" syntax\*
Loki's line filter syntax is great to find specific substrings of your log lines. If users want to find multiple different substrings it was cumbersome to use the regex `=~` operator. With this change it is possible to chain multiple strings with the existing filter operators.
Example:
```
{app="foo"} |= "foo" or "bar" != "baz" or "qux"
```
#### Filter based on label type\*
Grafana users can use the action buttons in the log details to filter for specific labels. Those would be always added as a LabelFilter expression regardless of the type of the label. Now, filtered labels will be added either to the stream selector if the label is an indexed label, or as a LabelFilter expression if the label is a parsed label or part of structured metadata.
#### Derived fields based on labels\*
Derived fields or data links are a concept to add correlations based on your log lines. Previously it was only possible to add derived fields based on a regular expression of your log line and doing it based on labels was not possible. With this change derived fields can be added either based on a regex of a log line or based on a label, parsed label or structured metadata.
The following example would add the derived field `traceID regex` based on a regular expression and another `app label` field based on the `app` label.
{{< figure src="/media/docs/grafana/2024-01-05_loki-derived-fields.png" >}}
### InfluxDB native SQL support
<!--Ismail Simsek-->
_Generally available in all editions of Grafana_
InfluxDB introduced [a new version, 3.0](https://www.influxdata.com/blog/introducing-influxdb-3-0/), in April. With this new version, InfluxDB has put [Flux in maintenance mode](https://www.influxdata.com/blog/the-plan-for-influxdb-3-0-open-source/#heading4). But with the new version we have a new querying language, [Native SQL](https://www.influxdata.com/products/sql/). With v10.3.0, Grafana has built-in support for SQL query language in InfluxDB.
All you need to do is set up your InfluxDB Cloud Account and create your InfluxDB data source on Grafana with the query language "SQL" selected.
{{< youtube id="jGclGsv5PBA" >}}
## Authentication and authorization
### Grafana Anonymous Access\*
<!--Eric Leijonmarck-->
_Generally available in Grafana Open Source and Enterprise_
We've identified a need for users who enable anonymous authentication to monitor the anonymous devices connected to their Grafana instance. This feature is part of our ongoing efforts to enhance control and transparency regarding anonymous usage.
Anonymous access now allows users, including those in open-source and enterprise self-managed environments, to view and monitor their anonymous access. They can also set a device limit, configuring a specific number of anonymous devices to connect to their instance.
Once this limit is reached, any new devices attempting to connect will be denied access until existing devices disconnect.
The anonymous devices feature improves the management and monitoring of anonymous access within your Grafana instance.
**Anonymous Device:**
When anonymous access has been enabled, any device which accesses Grafana in the last 30 days (without logging in) is considered an active anonymous device. Users can now view anonymous devices on the users page, anonymous usage statistics, including the count of devices and users over this period.
**Grafana UI:**
- Navigate to Administration -> Users to access the anonymous devices tab.
- A new statistic has been added to the Usage & Stats page, displaying active anonymous devices from the last 30 days.
{{< youtube id="B72X3_9e-ds" >}}
[Documentation](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-security/configure-authentication/grafana/)

View File

@@ -1,3 +1,7 @@
---
draft: true
---
# Contribute to 'What's new in Grafana Cloud'
To contribute to [What's new in Grafana Cloud](https://grafana.com/docs/grafana-cloud/whatsnew/), refer to [Contribute to Whats new or release notes](https://grafana.com/docs/writers-toolkit/contribute-documentation/contribute-release-notes/).

View File

@@ -10,14 +10,6 @@ describe('Explore', () => {
e2e.pages.Explore.General.container().should('have.length', 1);
e2e.components.RefreshPicker.runButtonV2().should('have.length', 1);
// delete query history queries that would be unrelated
e2e.components.QueryTab.queryHistoryButton().should('be.visible').click();
cy.get('button[title="Delete query"]').each((button) => {
button.trigger('click');
});
cy.get('button[title="Delete query"]').should('not.exist');
e2e.components.QueryTab.queryHistoryButton().should('be.visible').click();
e2e.components.DataSource.TestData.QueryTab.scenarioSelectContainer()
.scrollIntoView()
.should('be.visible')
@@ -26,17 +18,5 @@ describe('Explore', () => {
});
cy.contains('CSV Metric Values').scrollIntoView().should('be.visible').click();
const canvases = cy.get('canvas');
canvases.should('have.length', 1);
// Both queries above should have been run and be shown in the query history
e2e.components.QueryTab.queryHistoryButton().should('be.visible').click();
e2e.components.QueryHistory.queryText().should('have.length', 1).should('contain', 'csv_metric_values');
// delete all queries
cy.get('button[title="Delete query"]').each((button) => {
button.trigger('click');
});
});
});

View File

@@ -0,0 +1,40 @@
<mjml>
<!-- global variables -->
<mj-include path="./partials/_globals.mjml" />
<!-- css styling -->
<mj-include path="./partials/layout/theme.css" type="css" css-inline="inline" />
<mj-head>
<!-- ⬇ Don't forget to specifify an email subject below! ⬇ -->
<mj-title>
{{ Subject .Subject .TemplateData "Verify your new email - {{.Name}}" }}
</mj-title>
<mj-include path="./partials/layout/head.mjml" />
</mj-head>
<mj-body>
<mj-section>
<mj-include path="./partials/layout/header.mjml" />
</mj-section>
<mj-section css-class="background">
<mj-column>
<mj-text>
<h2>Hi {{ .Name }},</h2>
</mj-text>
<mj-text>
Please click the following link to verify your email within <strong>{{ .VerificationEmailLifetimeHours }} hour(s)</strong>.
</mj-text>
<mj-button href="{{ .AppUrl }}user/email/update?code={{ .Code }}">
Verify Email
</mj-button>
<mj-text>
You can also copy and paste this link into your browser directly:
</mj-text>
<mj-text>
<a rel="noopener" href="{{ .AppUrl }}user/email/update?code={{ .Code }}">{{ .AppUrl }}user/email/update?code={{ .Code }}</a>
</mj-text>
</mj-column>
</mj-section>
<mj-section>
<mj-include path="./partials/layout/footer.mjml" />
</mj-section>
</mj-body>
</mjml>

View File

@@ -0,0 +1,6 @@
[[HiddenSubject .Subject "Verify your new email - [[.Name]]"]]
Hi [[.Name]],
Copy and paste the following link directly in your browser to verify your email within [[.VerificationEmailLifetimeHours]] hour(s).
[[.AppUrl]]user/email/update?code=[[.Code]]

2
go.mod
View File

@@ -306,7 +306,7 @@ require (
github.com/buildkite/yaml v2.1.0+incompatible // indirect
github.com/bwmarrin/snowflake v0.3.0 // @grafan/grafana-app-platform-squad
github.com/centrifugal/protocol v0.10.0 // indirect
github.com/cloudflare/circl v1.3.3 // indirect
github.com/cloudflare/circl v1.3.7 // indirect
github.com/cockroachdb/errors v1.9.1 // indirect
github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f // indirect
github.com/cockroachdb/redact v1.1.3 // indirect

3
go.sum
View File

@@ -888,8 +888,9 @@ github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp
github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng=
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=

View File

@@ -1,4 +1,5 @@
{
"__message": "This file is now deprecated, and will be removed in a future release. No further updates should be made to this file",
"stable": "10.2.3",
"testing": "10.2.3"
}

View File

@@ -1,4 +1,4 @@
{
"npmClient": "yarn",
"version": "10.3.0-pre"
"version": "10.3.3"
}

View File

@@ -3,7 +3,7 @@
"license": "AGPL-3.0-only",
"private": true,
"name": "grafana",
"version": "10.3.0-pre",
"version": "10.3.3",
"repository": "github:grafana/grafana",
"scripts": {
"prebuild": "yarn i18n:compile && yarn plugin:build",

View File

@@ -36,7 +36,7 @@ Every commit to main that has changes within the `packages` directory is a subje
> All of the steps below must be performed on a release branch, according to Grafana Release Guide.
> You must be logged in to NPM as part of Grafana NPM org before attempting to publish to the npm registery.
> You must be logged in to NPM as part of Grafana NPM org before attempting to publish to the npm registry.
1. Run `yarn packages:clean` script from the root directory. This will delete any previous builds of the packages.
2. Run `yarn packages:prepare` script from the root directory. This performs tests on the packages and prompts for the version of the packages. The version should be the same as the one being released.

View File

@@ -2,7 +2,7 @@
"author": "Grafana Labs",
"license": "Apache-2.0",
"name": "@grafana/data",
"version": "10.3.0-pre",
"version": "10.3.3",
"description": "Grafana Data Library",
"keywords": [
"typescript"
@@ -36,7 +36,7 @@
},
"dependencies": {
"@braintree/sanitize-url": "6.0.2",
"@grafana/schema": "10.3.0-pre",
"@grafana/schema": "10.3.3",
"@types/d3-interpolate": "^3.0.0",
"@types/string-hash": "1.1.1",
"d3-interpolate": "3.0.1",

View File

@@ -1,5 +1,3 @@
import { isEqual } from 'lodash';
import { DataFrame, Field, TIME_SERIES_VALUE_FIELD_NAME, FieldType, TIME_SERIES_TIME_FIELD_NAME } from '../types';
import { formatLabels } from '../utils/labels';
@@ -167,7 +165,7 @@ export function getUniqueFieldName(field: Field, frame?: DataFrame) {
for (let i = 0; i < frame.fields.length; i++) {
const otherField = frame.fields[i];
if (isEqual(field, otherField)) {
if (field === otherField) {
foundSelf = true;
if (dupeCount > 0) {

View File

@@ -172,4 +172,5 @@ export interface FeatureToggles {
alertStateHistoryAnnotationsFromLoki?: boolean;
lokiQueryHints?: boolean;
alertingPreviewUpgrade?: boolean;
newFolderPicker?: boolean;
}

View File

@@ -2,7 +2,7 @@
"author": "Grafana Labs",
"license": "Apache-2.0",
"name": "@grafana/e2e-selectors",
"version": "10.3.0-pre",
"version": "10.3.3",
"description": "Grafana End-to-End Test Selectors Library",
"keywords": [
"cli",

View File

@@ -2,7 +2,7 @@
"author": "Grafana Labs",
"license": "Apache-2.0",
"name": "@grafana/e2e",
"version": "10.3.0-pre",
"version": "10.3.3",
"description": "Grafana End-to-End Test Library",
"keywords": [
"cli",
@@ -63,8 +63,8 @@
"@babel/core": "7.23.2",
"@babel/preset-env": "7.23.2",
"@cypress/webpack-preprocessor": "5.17.1",
"@grafana/e2e-selectors": "10.3.0-pre",
"@grafana/schema": "10.3.0-pre",
"@grafana/e2e-selectors": "10.3.3",
"@grafana/schema": "10.3.3",
"@grafana/tsconfig": "^1.2.0-rc1",
"@mochajs/json-file-reporter": "^1.2.0",
"babel-loader": "9.1.3",

View File

@@ -1,7 +1,7 @@
{
"name": "@grafana/eslint-plugin",
"description": "ESLint rules for use within the Grafana repo. Not suitable (or supported) for external use.",
"version": "10.3.0-pre",
"version": "10.3.3",
"main": "./index.cjs",
"author": "Grafana Labs",
"license": "Apache-2.0",

View File

@@ -2,7 +2,7 @@
"author": "Grafana Labs",
"license": "Apache-2.0",
"name": "@grafana/flamegraph",
"version": "10.3.0-pre",
"version": "10.3.3",
"description": "Grafana flamegraph visualization component",
"keywords": [
"grafana",
@@ -44,8 +44,8 @@
],
"dependencies": {
"@emotion/css": "11.11.2",
"@grafana/data": "10.3.0-pre",
"@grafana/ui": "10.3.0-pre",
"@grafana/data": "10.3.3",
"@grafana/ui": "10.3.3",
"@leeoniya/ufuzzy": "1.0.13",
"d3": "^7.8.5",
"lodash": "4.17.21",

View File

@@ -2,7 +2,7 @@
"name": "@grafana/plugin-configs",
"description": "Shared dependencies and files for core plugins",
"private": true,
"version": "10.3.0-pre",
"version": "10.3.3",
"dependencies": {
"tslib": "2.6.0"
},

View File

@@ -2,7 +2,7 @@
"author": "Grafana Labs",
"license": "Apache-2.0",
"name": "@grafana/runtime",
"version": "10.3.0-pre",
"version": "10.3.3",
"description": "Grafana Runtime Library",
"keywords": [
"grafana",
@@ -37,10 +37,10 @@
"postpack": "mv package.json.bak package.json"
},
"dependencies": {
"@grafana/data": "10.3.0-pre",
"@grafana/e2e-selectors": "10.3.0-pre",
"@grafana/data": "10.3.3",
"@grafana/e2e-selectors": "10.3.3",
"@grafana/faro-web-sdk": "^1.3.5",
"@grafana/ui": "10.3.0-pre",
"@grafana/ui": "10.3.3",
"history": "4.10.1",
"lodash": "4.17.21",
"rxjs": "7.8.1",

View File

@@ -2,7 +2,7 @@
"author": "Grafana Labs",
"license": "Apache-2.0",
"name": "@grafana/schema",
"version": "10.3.0-pre",
"version": "10.3.3",
"description": "Grafana Schema Library",
"keywords": [
"typescript"

View File

@@ -9,7 +9,7 @@
//
// Run 'make gen-cue' from repository root to regenerate.
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
export interface Options {
/**

View File

@@ -9,7 +9,7 @@
//
// Run 'make gen-cue' from repository root to regenerate.
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
export interface Options {
limit: number;

View File

@@ -11,7 +11,7 @@
import * as common from '@grafana/schema';
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
export interface Options extends common.OptionsWithLegend, common.OptionsWithTooltip, common.OptionsWithTextFormatting {
/**

View File

@@ -11,7 +11,7 @@
import * as common from '@grafana/schema';
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
export interface Options extends common.SingleStatBaseOptions {
displayMode: common.BarGaugeDisplayMode;

View File

@@ -11,7 +11,7 @@
import * as common from '@grafana/schema';
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
export enum VizDisplayMode {
Candles = 'candles',

View File

@@ -11,7 +11,7 @@
import * as ui from '@grafana/schema';
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
export enum HorizontalConstraint {
Center = 'center',

View File

@@ -11,7 +11,7 @@
import * as common from '@grafana/schema';
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
export interface MetricStat {
/**

View File

@@ -9,7 +9,7 @@
//
// Run 'make gen-cue' from repository root to regenerate.
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
export interface Options {
/**

View File

@@ -9,7 +9,7 @@
//
// Run 'make gen-cue' from repository root to regenerate.
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
export interface Options {
selectedSeries: number;

View File

@@ -9,7 +9,7 @@
//
// Run 'make gen-cue' from repository root to regenerate.
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
export type UpdateConfig = {
render: boolean,

View File

@@ -11,7 +11,7 @@
import * as common from '@grafana/schema';
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
export type BucketAggregation = (DateHistogram | Histogram | Terms | Filters | GeoHashGrid | Nested);

View File

@@ -11,7 +11,7 @@
import * as common from '@grafana/schema';
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
export interface Options extends common.SingleStatBaseOptions {
minVizHeight: number;

View File

@@ -11,7 +11,7 @@
import * as ui from '@grafana/schema';
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
export interface Options {
basemap: ui.MapLayerOptions;

View File

@@ -11,7 +11,7 @@
import * as common from '@grafana/schema';
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
export type PyroscopeQueryType = ('metrics' | 'profile' | 'both');

View File

@@ -11,7 +11,7 @@
import * as ui from '@grafana/schema';
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
/**
* Controls the color mode of the heatmap

View File

@@ -11,7 +11,7 @@
import * as common from '@grafana/schema';
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
export interface Options extends common.OptionsWithLegend, common.OptionsWithTooltip {
/**

View File

@@ -11,7 +11,7 @@
import * as common from '@grafana/schema';
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
export interface Options {
dedupStrategy: common.LogsDedupStrategy;

View File

@@ -11,7 +11,7 @@
import * as common from '@grafana/schema';
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
export enum QueryEditorMode {
Builder = 'builder',

View File

@@ -9,7 +9,7 @@
//
// Run 'make gen-cue' from repository root to regenerate.
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
export interface Options {
/**

View File

@@ -9,7 +9,7 @@
//
// Run 'make gen-cue' from repository root to regenerate.
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
export interface ArcOption {
/**

View File

@@ -11,7 +11,7 @@
import * as common from '@grafana/schema';
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
/**
* Select the pie chart display style.

View File

@@ -11,7 +11,7 @@
import * as common from '@grafana/schema';
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
export enum QueryEditorMode {
Builder = 'builder',

View File

@@ -11,7 +11,7 @@
import * as common from '@grafana/schema';
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
export interface Options extends common.SingleStatBaseOptions {
colorMode: common.BigValueColorMode;

View File

@@ -11,7 +11,7 @@
import * as ui from '@grafana/schema';
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
export interface Options extends ui.OptionsWithLegend, ui.OptionsWithTooltip, ui.OptionsWithTimezones {
/**

View File

@@ -11,7 +11,7 @@
import * as ui from '@grafana/schema';
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
export interface Options extends ui.OptionsWithLegend, ui.OptionsWithTooltip, ui.OptionsWithTimezones {
/**

View File

@@ -11,7 +11,7 @@
import * as ui from '@grafana/schema';
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
export interface Options {
/**

View File

@@ -11,7 +11,7 @@
import * as common from '@grafana/schema';
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
export interface TempoQuery extends common.DataQuery {
filters: Array<TraceqlFilter>;

View File

@@ -9,7 +9,7 @@
//
// Run 'make gen-cue' from repository root to regenerate.
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
export enum TextMode {
Code = 'code',

View File

@@ -11,7 +11,7 @@
import * as common from '@grafana/schema';
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
export interface Options extends common.OptionsWithTimezones {
legend: common.VizLegendOptions;

View File

@@ -11,7 +11,7 @@
import * as common from '@grafana/schema';
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
/**
* Identical to timeseries... except it does not have timezone settings

View File

@@ -11,7 +11,7 @@
import * as common from '@grafana/schema';
export const pluginVersion = "10.3.0-pre";
export const pluginVersion = "10.3.3";
/**
* Auto is "table" in the UI

View File

@@ -2,7 +2,7 @@
"author": "Grafana Labs",
"license": "Apache-2.0",
"name": "@grafana/ui",
"version": "10.3.0-pre",
"version": "10.3.3",
"description": "Grafana Components Library",
"keywords": [
"grafana",
@@ -50,10 +50,10 @@
"@emotion/css": "11.11.2",
"@emotion/react": "11.11.1",
"@floating-ui/react": "0.26.4",
"@grafana/data": "10.3.0-pre",
"@grafana/e2e-selectors": "10.3.0-pre",
"@grafana/data": "10.3.3",
"@grafana/e2e-selectors": "10.3.3",
"@grafana/faro-web-sdk": "^1.3.5",
"@grafana/schema": "10.3.0-pre",
"@grafana/schema": "10.3.3",
"@leeoniya/ufuzzy": "1.0.13",
"@monaco-editor/react": "4.6.0",
"@popperjs/core": "2.11.8",

View File

@@ -606,7 +606,7 @@ func (hs *HTTPServer) declareFixedRoles() error {
Group: "Annotations",
Permissions: []ac.Permission{
{Action: ac.ActionAnnotationsRead, Scope: ac.ScopeAnnotationsTypeOrganization},
{Action: ac.ActionAnnotationsRead, Scope: dashboards.ScopeDashboardsAll},
{Action: ac.ActionAnnotationsRead, Scope: dashboards.ScopeFoldersAll},
},
},
Grants: []string{string(org.RoleAdmin)},
@@ -620,11 +620,11 @@ func (hs *HTTPServer) declareFixedRoles() error {
Group: "Annotations",
Permissions: []ac.Permission{
{Action: ac.ActionAnnotationsCreate, Scope: ac.ScopeAnnotationsTypeOrganization},
{Action: ac.ActionAnnotationsCreate, Scope: dashboards.ScopeDashboardsAll},
{Action: ac.ActionAnnotationsCreate, Scope: dashboards.ScopeFoldersAll},
{Action: ac.ActionAnnotationsDelete, Scope: ac.ScopeAnnotationsTypeOrganization},
{Action: ac.ActionAnnotationsDelete, Scope: dashboards.ScopeDashboardsAll},
{Action: ac.ActionAnnotationsDelete, Scope: dashboards.ScopeFoldersAll},
{Action: ac.ActionAnnotationsWrite, Scope: ac.ScopeAnnotationsTypeOrganization},
{Action: ac.ActionAnnotationsWrite, Scope: dashboards.ScopeDashboardsAll},
{Action: ac.ActionAnnotationsWrite, Scope: dashboards.ScopeFoldersAll},
},
},
Grants: []string{string(org.RoleAdmin)},

View File

@@ -193,6 +193,11 @@ func (hs *HTTPServer) registerRoutes() {
r.Post("/api/user/signup", quota(user.QuotaTargetSrv), quota(org.QuotaTargetSrv), routing.Wrap(hs.SignUp))
r.Post("/api/user/signup/step2", routing.Wrap(hs.SignUpStep2))
// update user email
if hs.Cfg.Smtp.Enabled && setting.VerifyEmailEnabled {
r.Get("/user/email/update", reqSignedInNoAnonymous, routing.Wrap(hs.UpdateUserEmail))
}
// invited
r.Get("/api/user/invite/:code", routing.Wrap(hs.GetInviteInfoByCode))
r.Post("/api/user/invite/complete", routing.Wrap(hs.CompleteInvite))

View File

@@ -179,7 +179,7 @@ type HTTPServer struct {
queryDataService query.Service
serviceAccountsService serviceaccounts.Service
authInfoService login.AuthInfoService
NotificationService *notifications.NotificationService
NotificationService notifications.Service
DashboardService dashboards.DashboardService
dashboardProvisioningService dashboards.DashboardProvisioningService
folderService folder.Service
@@ -242,7 +242,7 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi
dataSourcesService datasources.DataSourceService, queryDataService query.Service, pluginFileStore plugins.FileStore,
serviceaccountsService serviceaccounts.Service,
authInfoService login.AuthInfoService, storageService store.StorageService,
notificationService *notifications.NotificationService, dashboardService dashboards.DashboardService,
notificationService notifications.Service, dashboardService dashboards.DashboardService,
dashboardProvisioningService dashboards.DashboardProvisioningService, folderService folder.Service,
dsGuardian guardian.DatasourceGuardianProvider, alertNotificationService *alerting.AlertNotificationService,
dashboardsnapshotsService dashboardsnapshots.Service, pluginSettings pluginSettings.Service,

View File

@@ -4,17 +4,23 @@ import (
"context"
"errors"
"net/http"
"net/mail"
"net/url"
"strconv"
"strings"
"time"
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/services/auth/identity"
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
"github.com/grafana/grafana/pkg/services/login"
"github.com/grafana/grafana/pkg/services/notifications"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/team"
tempuser "github.com/grafana/grafana/pkg/services/temp_user"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web"
)
@@ -125,6 +131,7 @@ func (hs *HTTPServer) GetUserByLoginOrEmail(c *contextmodel.ReqContext) response
// 200: okResponse
// 401: unauthorisedError
// 403: forbiddenError
// 409: conflictError
// 500: internalServerError
func (hs *HTTPServer) UpdateSignedInUser(c *contextmodel.ReqContext) response.Response {
cmd := user.UpdateUserCommand{}
@@ -165,6 +172,7 @@ func (hs *HTTPServer) UpdateSignedInUser(c *contextmodel.ReqContext) response.Re
// 401: unauthorisedError
// 403: forbiddenError
// 404: notFoundError
// 409: conflictError
// 500: internalServerError
func (hs *HTTPServer) UpdateUser(c *contextmodel.ReqContext) response.Response {
cmd := user.UpdateUserCommand{}
@@ -228,6 +236,39 @@ func (hs *HTTPServer) handleUpdateUser(ctx context.Context, cmd user.UpdateUserC
return response.Err(user.ErrEmptyUsernameAndEmail.Errorf("user cannot be created with empty username and email"))
}
// If email is being updated, we need to verify it. Likewise, if username is being updated and the new username
// is an email, we also need to verify it.
// To avoid breaking changes, email verification is implemented in a way that if the email field is being updated,
// all the other fields being updated in the same request are disregarded. We do this because email might need to
// be verified and if so, it goes through a different code flow.
if hs.Cfg.Smtp.Enabled && setting.VerifyEmailEnabled {
query := user.GetUserByIDQuery{ID: cmd.UserID}
usr, err := hs.userService.GetByID(ctx, &query)
if err != nil {
if errors.Is(err, user.ErrUserNotFound) {
return response.Error(http.StatusNotFound, user.ErrUserNotFound.Error(), nil)
}
return response.Error(http.StatusInternalServerError, "Failed to get user", err)
}
if len(cmd.Email) != 0 && usr.Email != cmd.Email {
// Email is being updated
newEmail, err := ValidateAndNormalizeEmail(cmd.Email)
if err != nil {
return response.Error(http.StatusBadRequest, "Invalid email address", err)
}
return hs.verifyEmailUpdate(ctx, newEmail, user.EmailUpdateAction, usr)
}
if len(cmd.Login) != 0 && usr.Login != cmd.Login {
// Username is being updated. If it's an email, go through the email verification flow
newEmailLogin, err := ValidateAndNormalizeEmail(cmd.Login)
if err == nil && newEmailLogin != usr.Email {
return hs.verifyEmailUpdate(ctx, newEmailLogin, user.LoginUpdateAction, usr)
}
}
}
if err := hs.userService.Update(ctx, &cmd); err != nil {
if errors.Is(err, user.ErrCaseInsensitive) {
return response.Error(http.StatusConflict, "Update would result in user login conflict", err)
@@ -238,6 +279,104 @@ func (hs *HTTPServer) handleUpdateUser(ctx context.Context, cmd user.UpdateUserC
return response.Success("User updated")
}
func (hs *HTTPServer) verifyEmailUpdate(ctx context.Context, email string, field user.UpdateEmailActionType, usr *user.User) response.Response {
// Verify that email is not already being used
query := user.GetUserByLoginQuery{LoginOrEmail: email}
existingUsr, err := hs.userService.GetByLogin(ctx, &query)
if err != nil && !errors.Is(err, user.ErrUserNotFound) {
return response.Error(http.StatusInternalServerError, "Failed to validate if email is already in use", err)
}
if existingUsr != nil {
return response.Error(http.StatusConflict, "Email is already being used", nil)
}
// Invalidate any pending verifications for this user
expireCmd := tempuser.ExpirePreviousVerificationsCommand{InvitedByUserID: usr.ID}
err = hs.tempUserService.ExpirePreviousVerifications(ctx, &expireCmd)
if err != nil {
return response.Error(http.StatusInternalServerError, "Could not invalidate pending email verifications", err)
}
code, err := util.GetRandomString(20)
if err != nil {
return response.Error(http.StatusInternalServerError, "Failed to generate random string", err)
}
tempCmd := tempuser.CreateTempUserCommand{
OrgID: -1,
Email: email,
Code: code,
Status: tempuser.TmpUserEmailUpdateStarted,
// used to fetch the User in the second step of the verification flow
InvitedByUserID: usr.ID,
// used to determine if the user was updating their email or username in the second step of the verification flow
Name: string(field),
}
tempUser, err := hs.tempUserService.CreateTempUser(ctx, &tempCmd)
if err != nil {
return response.Error(http.StatusInternalServerError, "Failed to create email change", err)
}
emailCmd := notifications.SendVerifyEmailCommand{Email: tempUser.Email, Code: tempUser.Code, User: usr}
err = hs.NotificationService.SendVerificationEmail(ctx, &emailCmd)
if err != nil {
return response.Error(http.StatusInternalServerError, "Failed to send verification email", err)
}
// Record email as sent
emailSentCmd := tempuser.UpdateTempUserWithEmailSentCommand{Code: tempUser.Code}
err = hs.tempUserService.UpdateTempUserWithEmailSent(ctx, &emailSentCmd)
if err != nil {
return response.Error(http.StatusInternalServerError, "Failed to record verification email", err)
}
return response.Success("Email sent for verification")
}
// swagger:route GET /user/email/update user updateUserEmail
//
// Update user email.
//
// Update the email of user given a verification code.
//
// Responses:
// 302: okResponse
func (hs *HTTPServer) UpdateUserEmail(c *contextmodel.ReqContext) response.Response {
var err error
q := c.Req.URL.Query()
code, err := url.QueryUnescape(q.Get("code"))
if err != nil || code == "" {
return hs.RedirectResponseWithError(c, errors.New("bad request data"))
}
tempUser, err := hs.validateEmailCode(c.Req.Context(), code)
if err != nil {
return hs.RedirectResponseWithError(c, err)
}
cmd, err := hs.updateCmdFromEmailVerification(c.Req.Context(), tempUser)
if err != nil {
return hs.RedirectResponseWithError(c, err)
}
if err := hs.userService.Update(c.Req.Context(), cmd); err != nil {
if errors.Is(err, user.ErrCaseInsensitive) {
return hs.RedirectResponseWithError(c, errors.New("update would result in user login conflict"))
}
return hs.RedirectResponseWithError(c, errors.New("failed to update user"))
}
// Mark temp user as completed
updateTmpUserCmd := tempuser.UpdateTempUserStatusCommand{Code: code, Status: tempuser.TmpUserEmailUpdateCompleted}
if err := hs.tempUserService.UpdateTempUserStatus(c.Req.Context(), &updateTmpUserCmd); err != nil {
return hs.RedirectResponseWithError(c, errors.New("failed to update verification status"))
}
return response.Redirect(hs.Cfg.AppSubURL + "/profile")
}
func (hs *HTTPServer) isExternalUser(ctx context.Context, userID int64) (bool, error) {
getAuthQuery := login.GetAuthInfoQuery{UserId: userID}
var err error
@@ -602,6 +741,57 @@ func getUserID(c *contextmodel.ReqContext) (int64, *response.NormalResponse) {
return userID, nil
}
func (hs *HTTPServer) updateCmdFromEmailVerification(ctx context.Context, tempUser *tempuser.TempUserDTO) (*user.UpdateUserCommand, error) {
userQuery := user.GetUserByLoginQuery{LoginOrEmail: tempUser.InvitedByLogin}
usr, err := hs.userService.GetByLogin(ctx, &userQuery)
if err != nil {
if errors.Is(err, user.ErrUserNotFound) {
return nil, user.ErrUserNotFound
}
return nil, errors.New("failed to get user")
}
cmd := &user.UpdateUserCommand{UserID: usr.ID, Email: tempUser.Email}
switch tempUser.Name {
case string(user.EmailUpdateAction):
// User updated the email field
if _, err := mail.ParseAddress(usr.Login); err == nil {
// If username was also an email, we update it to keep it in sync with the email field
cmd.Login = tempUser.Email
}
case string(user.LoginUpdateAction):
// User updated the username field with a new email
cmd.Login = tempUser.Email
default:
return nil, errors.New("trying to update email on unknown field")
}
return cmd, nil
}
func (hs *HTTPServer) validateEmailCode(ctx context.Context, code string) (*tempuser.TempUserDTO, error) {
tempUserQuery := tempuser.GetTempUserByCodeQuery{Code: code}
tempUser, err := hs.tempUserService.GetTempUserByCode(ctx, &tempUserQuery)
if err != nil {
if errors.Is(err, tempuser.ErrTempUserNotFound) {
return nil, errors.New("invalid email verification code")
}
return nil, errors.New("failed to read temp user")
}
if tempUser.Status != tempuser.TmpUserEmailUpdateStarted {
return nil, errors.New("invalid email verification code")
}
if !tempUser.EmailSent {
return nil, errors.New("verification email was not recorded as sent")
}
if tempUser.EmailSentOn.Add(hs.Cfg.VerificationEmailMaxLifetime).Before(time.Now()) {
return nil, errors.New("invalid email verification code")
}
return tempUser, nil
}
// swagger:parameters searchUsers
type SearchUsersParams struct {
// Limit the maximum number of users to return per page

View File

@@ -5,9 +5,18 @@ import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"strings"
"testing"
"time"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/notifications"
"github.com/grafana/grafana/pkg/services/secrets/fakes"
tempuser "github.com/grafana/grafana/pkg/services/temp_user"
"github.com/grafana/grafana/pkg/services/temp_user/tempuserimpl"
"github.com/grafana/grafana/pkg/web/webtest"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/oauth2"
@@ -39,6 +48,8 @@ import (
"github.com/grafana/grafana/pkg/setting"
)
const newEmail = "newEmail@localhost"
func TestUserAPIEndpoint_userLoggedIn(t *testing.T) {
settings := setting.NewCfg()
sqlStore := db.InitTestDB(t)
@@ -69,7 +80,6 @@ func TestUserAPIEndpoint_userLoggedIn(t *testing.T) {
hs.authInfoService = srv
orgSvc, err := orgimpl.ProvideService(sqlStore, sqlStore.Cfg, quotatest.New(false, nil))
require.NoError(t, err)
require.NoError(t, err)
userSvc, err := userimpl.ProvideService(sqlStore, orgSvc, sc.cfg, nil, nil, quotatest.New(false, nil), supportbundlestest.NewFakeBundleService())
require.NoError(t, err)
hs.userService = userSvc
@@ -361,6 +371,681 @@ func TestHTTPServer_UpdateUser(t *testing.T) {
}, hs)
}
func setupUpdateEmailTests(t *testing.T, cfg *setting.Cfg) (*user.User, *HTTPServer, *notifications.NotificationServiceMock) {
t.Helper()
sqlStore := db.InitTestDB(t)
sqlStore.Cfg = cfg
tempUserService := tempuserimpl.ProvideService(sqlStore, cfg)
orgSvc, err := orgimpl.ProvideService(sqlStore, cfg, quotatest.New(false, nil))
require.NoError(t, err)
userSvc, err := userimpl.ProvideService(sqlStore, orgSvc, cfg, nil, nil, quotatest.New(false, nil), supportbundlestest.NewFakeBundleService())
require.NoError(t, err)
// Create test user
createUserCmd := user.CreateUserCommand{
Email: "testuser@localhost",
Name: "testuser",
Login: "loginuser",
Company: "testCompany",
IsAdmin: true,
}
usr, err := userSvc.Create(context.Background(), &createUserCmd)
require.NoError(t, err)
nsMock := notifications.MockNotificationService()
hs := &HTTPServer{
Cfg: cfg,
SQLStore: sqlStore,
userService: userSvc,
tempUserService: tempUserService,
NotificationService: nsMock,
}
return usr, hs, nsMock
}
func TestUser_UpdateEmail(t *testing.T) {
cases := []struct {
Name string
Field user.UpdateEmailActionType
}{
{
Name: "Updating Email field",
Field: user.EmailUpdateAction,
},
{
Name: "Updating Login (username) field",
Field: user.LoginUpdateAction,
},
}
for _, tt := range cases {
t.Run(tt.Name, func(t *testing.T) {
t.Run("With verification disabled should update without verifying", func(t *testing.T) {
tests := []struct {
name string
smtpConfigured bool
verifyEmailEnabled bool
}{
{
name: "SMTP not configured",
smtpConfigured: false,
verifyEmailEnabled: true,
},
{
name: "config verify_email_enabled = false",
smtpConfigured: true,
verifyEmailEnabled: false,
},
{
name: "config verify_email_enabled = false and SMTP not configured",
smtpConfigured: false,
verifyEmailEnabled: false,
},
}
for _, ttt := range tests {
settings := setting.NewCfg()
settings.Smtp.Enabled = ttt.smtpConfigured
setting.VerifyEmailEnabled = ttt.verifyEmailEnabled
usr, hs, nsMock := setupUpdateEmailTests(t, settings)
updateUserCommand := user.UpdateUserCommand{
Email: usr.Email,
Name: "newName",
Login: usr.Login,
UserID: usr.ID,
}
switch tt.Field {
case user.LoginUpdateAction:
updateUserCommand.Login = newEmail
case user.EmailUpdateAction:
updateUserCommand.Email = newEmail
}
fn := func(sc *scenarioContext) {
// User is internal
sc.authInfoService.ExpectedError = user.ErrUserNotFound
sc.fakeReqWithParams("PUT", sc.url, nil).exec()
assert.Equal(t, http.StatusOK, sc.resp.Code)
// Verify that no email has been sent after update
require.False(t, nsMock.EmailVerified)
userQuery := user.GetUserByIDQuery{ID: usr.ID}
updatedUsr, err := hs.userService.GetByID(context.Background(), &userQuery)
require.NoError(t, err)
// Verify fields have been updated
require.NotEqual(t, usr.Name, updatedUsr.Name)
require.Equal(t, updateUserCommand.Name, updatedUsr.Name)
switch tt.Field {
case user.LoginUpdateAction:
require.Equal(t, usr.Email, updatedUsr.Email)
require.NotEqual(t, usr.Login, updatedUsr.Login)
require.Equal(t, updateUserCommand.Login, updatedUsr.Login)
case user.EmailUpdateAction:
require.Equal(t, usr.Login, updatedUsr.Login)
require.NotEqual(t, usr.Email, updatedUsr.Email)
require.Equal(t, updateUserCommand.Email, updatedUsr.Email)
}
// Verify other fields have been kept
require.Equal(t, usr.Company, updatedUsr.Company)
}
updateUserScenario(t, updateUserContext{
desc: ttt.name,
url: fmt.Sprintf("/api/users/%d", usr.ID),
routePattern: "/api/users/:id",
cmd: updateUserCommand,
fn: fn,
}, hs)
updateSignedInUserScenario(t, updateUserContext{
desc: ttt.name,
url: "/api/user",
routePattern: "/api/user",
cmd: updateUserCommand,
fn: fn,
}, hs)
}
})
})
}
doReq := func(req *http.Request, usr *user.User) (*http.Response, error) {
r := webtest.RequestWithSignedInUser(
req,
authedUserWithPermissions(
usr.ID,
usr.OrgID,
[]accesscontrol.Permission{
{
Action: accesscontrol.ActionUsersWrite,
Scope: accesscontrol.ScopeGlobalUsersAll,
},
},
),
)
client := &http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
}}
return client.Do(r)
}
sendUpdateReq := func(server *webtest.Server, usr *user.User, body string) {
req := server.NewRequest(
http.MethodPut,
"/api/user",
strings.NewReader(body),
)
req.Header.Add("Content-Type", "application/json")
res, err := doReq(req, usr)
require.NoError(t, err)
assert.Equal(t, http.StatusOK, res.StatusCode)
require.NoError(t, res.Body.Close())
}
sendVerificationReq := func(server *webtest.Server, usr *user.User, code string) {
url := fmt.Sprintf("/user/email/update?code=%s", url.QueryEscape(code))
req := server.NewGetRequest(url)
res, err := doReq(req, usr)
require.NoError(t, err)
assert.Equal(t, http.StatusFound, res.StatusCode)
require.NoError(t, res.Body.Close())
}
getVerificationTempUser := func(tempUserSvc tempuser.Service, code string) *tempuser.TempUserDTO {
tmpUserQuery := tempuser.GetTempUserByCodeQuery{Code: code}
tmpUser, err := tempUserSvc.GetTempUserByCode(context.Background(), &tmpUserQuery)
require.NoError(t, err)
return tmpUser
}
verifyEmailData := func(tempUserSvc tempuser.Service, nsMock *notifications.NotificationServiceMock, originalUsr *user.User, newEmail string) {
verification := nsMock.EmailVerification
tmpUsr := getVerificationTempUser(tempUserSvc, verification.Code)
require.True(t, nsMock.EmailVerified)
require.Equal(t, newEmail, verification.Email)
require.Equal(t, originalUsr.ID, verification.User.ID)
require.Equal(t, tmpUsr.Code, verification.Code)
}
verifyUserNotUpdated := func(userSvc user.Service, usr *user.User) {
userQuery := user.GetUserByIDQuery{ID: usr.ID}
checkUsr, err := userSvc.GetByID(context.Background(), &userQuery)
require.NoError(t, err)
require.Equal(t, usr.Email, checkUsr.Email)
require.Equal(t, usr.Login, checkUsr.Login)
require.Equal(t, usr.Name, checkUsr.Name)
}
setupScenario := func(cfg *setting.Cfg) (*webtest.Server, user.Service, tempuser.Service, *notifications.NotificationServiceMock) {
setting.VerifyEmailEnabled = true
settings := setting.NewCfg()
settings.Smtp.Enabled = true
settings.VerificationEmailMaxLifetime = 1 * time.Hour
if cfg != nil {
settings = cfg
}
nsMock := notifications.MockNotificationService()
sqlStore := db.InitTestDB(t)
sqlStore.Cfg = settings
tempUserSvc := tempuserimpl.ProvideService(sqlStore, settings)
orgSvc, err := orgimpl.ProvideService(sqlStore, settings, quotatest.New(false, nil))
require.NoError(t, err)
userSvc, err := userimpl.ProvideService(sqlStore, orgSvc, settings, nil, nil, quotatest.New(false, nil), supportbundlestest.NewFakeBundleService())
require.NoError(t, err)
server := SetupAPITestServer(t, func(hs *HTTPServer) {
hs.Cfg = settings
hs.SQLStore = sqlStore
hs.userService = userSvc
hs.tempUserService = tempUserSvc
hs.NotificationService = nsMock
hs.SecretsService = fakes.NewFakeSecretsService()
// User is internal
hs.authInfoService = &authinfotest.FakeService{ExpectedError: user.ErrUserNotFound}
})
return server, userSvc, tempUserSvc, nsMock
}
createUser := func(userSvc user.Service, name string, email string, login string) *user.User {
createUserCmd := user.CreateUserCommand{
Email: email,
Name: name,
Login: login,
Company: "testCompany",
IsAdmin: true,
}
usr, err := userSvc.Create(context.Background(), &createUserCmd)
require.NoError(t, err)
return usr
}
t.Run("Update Email and disregard other fields", func(t *testing.T) {
server, userSvc, tempUserSvc, nsMock := setupScenario(nil)
originalUsr := createUser(userSvc, "name", "email@localhost", "login")
// Verify that no email has been sent yet
require.False(t, nsMock.EmailVerified)
// Start email update
newName := "newName"
body := fmt.Sprintf(`{"email": "%s", "name": "%s"}`, newEmail, newName)
sendUpdateReq(server, originalUsr, body)
// Verify email data
verifyEmailData(tempUserSvc, nsMock, originalUsr, newEmail)
// Verify user has not been updated yet
verifyUserNotUpdated(userSvc, originalUsr)
// Second part of the verification flow, when user clicks email button
code := nsMock.EmailVerification.Code
sendVerificationReq(server, originalUsr, code)
// Verify Email has been updated
userQuery := user.GetUserByIDQuery{ID: originalUsr.ID}
updatedUsr, err := userSvc.GetByID(context.Background(), &userQuery)
require.NoError(t, err)
require.NotEqual(t, originalUsr.Email, updatedUsr.Email)
require.Equal(t, newEmail, updatedUsr.Email)
// Fields unchanged
require.Equal(t, originalUsr.Login, updatedUsr.Login)
require.Equal(t, originalUsr.Name, updatedUsr.Name)
require.NotEqual(t, newName, updatedUsr.Name)
})
t.Run("Update Email when Login was also an email should update both", func(t *testing.T) {
server, userSvc, tempUserSvc, nsMock := setupScenario(nil)
originalUsr := createUser(userSvc, "name", "email@localhost", "email@localhost")
// Verify that no email has been sent yet
require.False(t, nsMock.EmailVerified)
// Start email update
body := fmt.Sprintf(`{"email": "%s"}`, newEmail)
sendUpdateReq(server, originalUsr, body)
// Verify email data
verifyEmailData(tempUserSvc, nsMock, originalUsr, newEmail)
// Verify user has not been updated yet
verifyUserNotUpdated(userSvc, originalUsr)
// Second part of the verification flow, when user clicks email button
code := nsMock.EmailVerification.Code
sendVerificationReq(server, originalUsr, code)
// Verify Email and Login have been updated
userQuery := user.GetUserByIDQuery{ID: originalUsr.ID}
updatedUsr, err := userSvc.GetByID(context.Background(), &userQuery)
require.NoError(t, err)
require.NotEqual(t, originalUsr.Email, updatedUsr.Email)
require.Equal(t, newEmail, updatedUsr.Email)
require.Equal(t, newEmail, updatedUsr.Login)
// Fields unchanged
require.Equal(t, originalUsr.Name, updatedUsr.Name)
})
t.Run("Update Login with an email should update Email too", func(t *testing.T) {
server, userSvc, tempUserSvc, nsMock := setupScenario(nil)
originalUsr := createUser(userSvc, "name", "email@localhost", "login")
// Verify that no email has been sent yet
require.False(t, nsMock.EmailVerified)
// Start email update
body := fmt.Sprintf(`{"login": "%s"}`, newEmail)
sendUpdateReq(server, originalUsr, body)
// Verify email data
verifyEmailData(tempUserSvc, nsMock, originalUsr, newEmail)
// Verify user has not been updated yet
verifyUserNotUpdated(userSvc, originalUsr)
// Second part of the verification flow, when user clicks email button
code := nsMock.EmailVerification.Code
sendVerificationReq(server, originalUsr, code)
// Verify Email and Login have been updated
userQuery := user.GetUserByIDQuery{ID: originalUsr.ID}
updatedUsr, err := userSvc.GetByID(context.Background(), &userQuery)
require.NoError(t, err)
require.NotEqual(t, originalUsr.Email, updatedUsr.Email)
require.NotEqual(t, originalUsr.Login, updatedUsr.Login)
require.Equal(t, newEmail, updatedUsr.Email)
require.Equal(t, newEmail, updatedUsr.Login)
// Fields unchanged
require.Equal(t, originalUsr.Name, updatedUsr.Name)
})
t.Run("Update Login should not need verification if it is not an email", func(t *testing.T) {
server, userSvc, _, nsMock := setupScenario(nil)
originalUsr := createUser(userSvc, "name", "email@localhost", "login")
// Verify that no email has been sent yet
require.False(t, nsMock.EmailVerified)
// Start email update
newLogin := "newLogin"
newName := "newName"
body := fmt.Sprintf(`{"login": "%s", "name": "%s"}`, newLogin, newName)
sendUpdateReq(server, originalUsr, body)
// Verify that email has not been sent
require.False(t, nsMock.EmailVerified)
// Verify Login has been updated
userQuery := user.GetUserByIDQuery{ID: originalUsr.ID}
updatedUsr, err := userSvc.GetByID(context.Background(), &userQuery)
require.NoError(t, err)
require.NotEqual(t, originalUsr.Login, updatedUsr.Login)
require.NotEqual(t, originalUsr.Name, updatedUsr.Name)
require.Equal(t, newLogin, updatedUsr.Login)
require.Equal(t, newName, updatedUsr.Name)
// Fields unchanged
require.Equal(t, originalUsr.Email, updatedUsr.Email)
})
t.Run("Update Login should not need verification if it is being updated to the already configured email", func(t *testing.T) {
server, userSvc, _, nsMock := setupScenario(nil)
originalUsr := createUser(userSvc, "name", "email@localhost", "login")
// Verify that no email has been sent yet
require.False(t, nsMock.EmailVerified)
// Start email update
body := fmt.Sprintf(`{"login": "%s"}`, originalUsr.Email)
sendUpdateReq(server, originalUsr, body)
// Verify that email has not been sent
require.False(t, nsMock.EmailVerified)
// Verify Login has been updated
userQuery := user.GetUserByIDQuery{ID: originalUsr.ID}
updatedUsr, err := userSvc.GetByID(context.Background(), &userQuery)
require.NoError(t, err)
require.NotEqual(t, originalUsr.Login, updatedUsr.Login)
require.Equal(t, originalUsr.Email, updatedUsr.Login)
require.Equal(t, originalUsr.Email, updatedUsr.Email)
})
t.Run("Update Login and Email with different email values at once should disregard the Login update", func(t *testing.T) {
server, userSvc, tempUserSvc, nsMock := setupScenario(nil)
originalUsr := createUser(userSvc, "name", "email@localhost", "login")
// Verify that no email has been sent yet
require.False(t, nsMock.EmailVerified)
// Start email update
newLogin := "newEmail2@localhost"
body := fmt.Sprintf(`{"email": "%s", "login": "%s"}`, newEmail, newLogin)
sendUpdateReq(server, originalUsr, body)
// Verify email data
verifyEmailData(tempUserSvc, nsMock, originalUsr, newEmail)
// Verify user has not been updated yet
verifyUserNotUpdated(userSvc, originalUsr)
// Second part of the verification flow, when user clicks email button
code := nsMock.EmailVerification.Code
sendVerificationReq(server, originalUsr, code)
// Verify only Email has been updated
userQuery := user.GetUserByIDQuery{ID: originalUsr.ID}
updatedUsr, err := userSvc.GetByID(context.Background(), &userQuery)
require.NoError(t, err)
require.NotEqual(t, originalUsr.Email, updatedUsr.Email)
require.Equal(t, newEmail, updatedUsr.Email)
// Fields unchanged
require.NotEqual(t, newLogin, updatedUsr.Login)
require.Equal(t, originalUsr.Login, updatedUsr.Login)
require.Equal(t, originalUsr.Name, updatedUsr.Name)
})
t.Run("Update Login and Email with different email values at once when Login was already an email should update both with Email", func(t *testing.T) {
server, userSvc, tempUserSvc, nsMock := setupScenario(nil)
originalUsr := createUser(userSvc, "name", "email@localhost", "email@localhost")
// Verify that no email has been sent yet
require.False(t, nsMock.EmailVerified)
// Start email update
newLogin := "newEmail2@localhost"
body := fmt.Sprintf(`{"email": "%s", "login": "%s"}`, newEmail, newLogin)
sendUpdateReq(server, originalUsr, body)
// Verify email data
verifyEmailData(tempUserSvc, nsMock, originalUsr, newEmail)
// Verify user has not been updated yet
verifyUserNotUpdated(userSvc, originalUsr)
// Second part of the verification flow, when user clicks email button
code := nsMock.EmailVerification.Code
sendVerificationReq(server, originalUsr, code)
// Verify only Email has been updated
userQuery := user.GetUserByIDQuery{ID: originalUsr.ID}
updatedUsr, err := userSvc.GetByID(context.Background(), &userQuery)
require.NoError(t, err)
require.NotEqual(t, originalUsr.Email, updatedUsr.Email)
require.NotEqual(t, originalUsr.Login, updatedUsr.Login)
require.NotEqual(t, newLogin, updatedUsr.Login)
require.Equal(t, newEmail, updatedUsr.Email)
require.Equal(t, newEmail, updatedUsr.Login)
// Fields unchanged
require.Equal(t, originalUsr.Name, updatedUsr.Name)
})
t.Run("Email verification should expire", func(t *testing.T) {
cfg := setting.NewCfg()
cfg.Smtp.Enabled = true
cfg.VerificationEmailMaxLifetime = 0 // Expire instantly
server, userSvc, tempUserSvc, nsMock := setupScenario(cfg)
originalUsr := createUser(userSvc, "name", "email@localhost", "login")
// Verify that no email has been sent yet
require.False(t, nsMock.EmailVerified)
// Start email update
body := fmt.Sprintf(`{"email": "%s"}`, newEmail)
sendUpdateReq(server, originalUsr, body)
// Verify email data
verifyEmailData(tempUserSvc, nsMock, originalUsr, newEmail)
// Verify user has not been updated yet
verifyUserNotUpdated(userSvc, originalUsr)
// Second part of the verification flow, when user clicks email button
code := nsMock.EmailVerification.Code
sendVerificationReq(server, originalUsr, code)
// Verify user has not been updated
userQuery := user.GetUserByIDQuery{ID: originalUsr.ID}
updatedUsr, err := userSvc.GetByID(context.Background(), &userQuery)
require.NoError(t, err)
require.NotEqual(t, newEmail, updatedUsr.Email)
require.Equal(t, originalUsr.Email, updatedUsr.Email)
require.Equal(t, originalUsr.Login, updatedUsr.Login)
})
t.Run("A new verification should revoke other pending verifications", func(t *testing.T) {
server, userSvc, tempUserSvc, nsMock := setupScenario(nil)
originalUsr := createUser(userSvc, "name", "email@localhost", "login")
// Verify that no email has been sent yet
require.False(t, nsMock.EmailVerified)
// First email verification
firstNewEmail := "newEmail1@localhost"
body := fmt.Sprintf(`{"email": "%s"}`, firstNewEmail)
sendUpdateReq(server, originalUsr, body)
verifyEmailData(tempUserSvc, nsMock, originalUsr, firstNewEmail)
firstCode := nsMock.EmailVerification.Code
// Second email verification
secondNewEmail := "newEmail2@localhost"
body = fmt.Sprintf(`{"email": "%s"}`, secondNewEmail)
sendUpdateReq(server, originalUsr, body)
verifyEmailData(tempUserSvc, nsMock, originalUsr, secondNewEmail)
secondCode := nsMock.EmailVerification.Code
// Verify user has not been updated yet
verifyUserNotUpdated(userSvc, originalUsr)
// Try to follow through with the first verification unsuccessfully
sendVerificationReq(server, originalUsr, firstCode)
verifyUserNotUpdated(userSvc, originalUsr)
// Follow through with second verification successfully
sendVerificationReq(server, originalUsr, secondCode)
userQuery := user.GetUserByIDQuery{ID: originalUsr.ID}
updatedUsr, err := userSvc.GetByID(context.Background(), &userQuery)
require.NoError(t, err)
require.NotEqual(t, originalUsr.Email, updatedUsr.Email)
require.Equal(t, secondNewEmail, updatedUsr.Email)
// Fields unchanged
require.Equal(t, originalUsr.Login, updatedUsr.Login)
})
t.Run("Email verification should fail if code is not valid", func(t *testing.T) {
server, userSvc, tempUserSvc, nsMock := setupScenario(nil)
originalUsr := createUser(userSvc, "name", "email@localhost", "login")
// Verify that no email has been sent yet
require.False(t, nsMock.EmailVerified)
// Start email update
body := fmt.Sprintf(`{"email": "%s"}`, newEmail)
sendUpdateReq(server, originalUsr, body)
// Verify email data
verifyEmailData(tempUserSvc, nsMock, originalUsr, newEmail)
// Verify user has not been updated yet
verifyUserNotUpdated(userSvc, originalUsr)
// Second part of the verification flow should fail if using the wrong code
sendVerificationReq(server, originalUsr, "notTheRightCode")
verifyUserNotUpdated(userSvc, originalUsr)
})
t.Run("Email verification code can only be used once", func(t *testing.T) {
server, userSvc, _, nsMock := setupScenario(nil)
originalUsr := createUser(userSvc, "name", "email@localhost", "login")
// Start email update
require.NotEqual(t, originalUsr.Email, newEmail)
body := fmt.Sprintf(`{"email": "%s"}`, newEmail)
sendUpdateReq(server, originalUsr, body)
// Verify user has not been updated yet
verifyUserNotUpdated(userSvc, originalUsr)
// Use code to verify successfully
codeToReuse := nsMock.EmailVerification.Code
sendVerificationReq(server, originalUsr, codeToReuse)
// User should have an updated Email
userQuery := user.GetUserByIDQuery{ID: originalUsr.ID}
updatedUsr, err := userSvc.GetByID(context.Background(), &userQuery)
require.NoError(t, err)
require.Equal(t, newEmail, updatedUsr.Email)
// Change email back to what it was
body = fmt.Sprintf(`{"email": "%s"}`, originalUsr.Email)
sendUpdateReq(server, originalUsr, body)
sendVerificationReq(server, originalUsr, nsMock.EmailVerification.Code)
verifyUserNotUpdated(userSvc, originalUsr)
// Re-use code to verify new email again, unsuccessfully
sendVerificationReq(server, originalUsr, codeToReuse)
verifyUserNotUpdated(userSvc, originalUsr)
})
t.Run("Update Email with an email that is already being used should fail", func(t *testing.T) {
testCases := []struct {
description string
clashLogin bool
}{
{
description: "when Email clashes",
clashLogin: false,
},
{
description: "when Login clashes",
clashLogin: true,
},
}
for _, tt := range testCases {
t.Run(tt.description, func(t *testing.T) {
server, userSvc, _, nsMock := setupScenario(nil)
originalUsr := createUser(userSvc, "name1", "email1@localhost", "login1@localhost")
badUsr := createUser(userSvc, "name2", "email2@localhost", "login2")
// Verify that no email has been sent yet
require.False(t, nsMock.EmailVerified)
// Update `badUsr` to use the same email as `originalUsr`
body := fmt.Sprintf(`{"email": "%s"}`, originalUsr.Email)
if tt.clashLogin {
body = fmt.Sprintf(`{"login": "%s"}`, originalUsr.Login)
}
req := server.NewRequest(
http.MethodPut,
"/api/user",
strings.NewReader(body),
)
req.Header.Add("Content-Type", "application/json")
res, err := doReq(req, badUsr)
require.NoError(t, err)
assert.Equal(t, http.StatusConflict, res.StatusCode)
require.NoError(t, res.Body.Close())
// Verify that no email has been sent
require.False(t, nsMock.EmailVerified)
// Verify user has not been updated
verifyUserNotUpdated(userSvc, badUsr)
})
}
})
}
type updateUserContext struct {
desc string
url string

View File

@@ -116,6 +116,27 @@ var DashboardViewActions = []string{dashboards.ActionDashboardsRead}
var DashboardEditActions = append(DashboardViewActions, []string{dashboards.ActionDashboardsWrite, dashboards.ActionDashboardsDelete}...)
var DashboardAdminActions = append(DashboardEditActions, []string{dashboards.ActionDashboardsPermissionsRead, dashboards.ActionDashboardsPermissionsWrite}...)
func getDashboardViewActions(features featuremgmt.FeatureToggles) []string {
if features.IsEnabled(context.Background(), featuremgmt.FlagAnnotationPermissionUpdate) {
return append(DashboardViewActions, accesscontrol.ActionAnnotationsRead)
}
return DashboardViewActions
}
func getDashboardEditActions(features featuremgmt.FeatureToggles) []string {
if features.IsEnabled(context.Background(), featuremgmt.FlagAnnotationPermissionUpdate) {
return append(DashboardEditActions, []string{accesscontrol.ActionAnnotationsRead, accesscontrol.ActionAnnotationsWrite, accesscontrol.ActionAnnotationsDelete, accesscontrol.ActionAnnotationsCreate}...)
}
return DashboardEditActions
}
func getDashboardAdminActions(features featuremgmt.FeatureToggles) []string {
if features.IsEnabled(context.Background(), featuremgmt.FlagAnnotationPermissionUpdate) {
return append(DashboardAdminActions, []string{accesscontrol.ActionAnnotationsRead, accesscontrol.ActionAnnotationsWrite, accesscontrol.ActionAnnotationsDelete, accesscontrol.ActionAnnotationsCreate}...)
}
return DashboardAdminActions
}
func ProvideDashboardPermissions(
features featuremgmt.FeatureToggles, router routing.RouteRegister, sql db.DB, ac accesscontrol.AccessControl,
license licensing.Licensing, dashboardStore dashboards.Store, folderService folder.Service, service accesscontrol.Service,
@@ -174,9 +195,9 @@ func ProvideDashboardPermissions(
ServiceAccounts: true,
},
PermissionsToActions: map[string][]string{
"View": DashboardViewActions,
"Edit": DashboardEditActions,
"Admin": DashboardAdminActions,
"View": getDashboardViewActions(features),
"Edit": getDashboardEditActions(features),
"Admin": getDashboardAdminActions(features),
},
ReaderRoleName: "Dashboard permission reader",
WriterRoleName: "Dashboard permission writer",
@@ -239,9 +260,9 @@ func ProvideFolderPermissions(
ServiceAccounts: true,
},
PermissionsToActions: map[string][]string{
"View": append(DashboardViewActions, FolderViewActions...),
"Edit": append(DashboardEditActions, FolderEditActions...),
"Admin": append(DashboardAdminActions, FolderAdminActions...),
"View": append(getDashboardViewActions(features), FolderViewActions...),
"Edit": append(getDashboardEditActions(features), FolderEditActions...),
"Admin": append(getDashboardAdminActions(features), FolderAdminActions...),
},
ReaderRoleName: "Folder permission reader",
WriterRoleName: "Folder permission writer",
@@ -283,7 +304,6 @@ func (e DatasourcePermissionsService) SetPermissions(ctx context.Context, orgID
}
func (e DatasourcePermissionsService) DeleteResourcePermissions(ctx context.Context, orgID int64, resourceID string) error {
// TODO: implement
return nil
}

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